diff --git a/.gitignore b/.gitignore index 9cee5e4d..000f5b10 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ typechain # yarn yarn-error.log package-lock.json + +dist diff --git a/.prettierignore b/.prettierignore index 04aaaebc..2c35a9b8 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,7 +3,6 @@ artifacts cache dist coverage -contracts/vendor typechain yarn.lock yarn-error.log diff --git a/.prettierrc.json b/.prettierrc.json index 6e388038..973e7f4c 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -3,13 +3,7 @@ { "files": "*.sol", "options": { - "compiler": "0.8.0" - } - }, - { - "files": "contracts/dependencies/GelatoCoreImport.sol", - "options": { - "compiler": "0.6.10" + "compiler": "0.8.12" } } ] diff --git a/.solhint.json b/.solhint.json index 092e3919..b28e8f51 100644 --- a/.solhint.json +++ b/.solhint.json @@ -6,7 +6,7 @@ "code-complexity": ["error", 5], "function-max-lines": ["error", 40], "max-line-length": ["error", 100], - "max-states-count": ["error", 3], + "max-states-count": ["warn", 3], "no-empty-blocks": "error", "no-unused-vars": "error", "payable-fallback": "off", @@ -32,7 +32,7 @@ "avoid-throw": "error", "avoid-tx-origin": "off", "check-send-result": "error", - "compiler-version": ["error", "0.8.0"], + "compiler-version": ["error", "^0.8.0"], "mark-callable-contracts": "off", "func-visibility": ["error", { "ignoreConstructors": true }], "multiple-sends": "error", diff --git a/.solhintignore b/.solhintignore index a9115cf8..da9b174a 100644 --- a/.solhintignore +++ b/.solhintignore @@ -1,8 +1,3 @@ node_modules/ -contracts/dependencies -contracts/diamond/facets/standard -contracts/diamond/interfaces/standard -contracts/diamond/libraries/standard -contracts/functions -contracts/vendor -contracts/diamond/__mocks__/MockUniV3Oracle/libraries \ No newline at end of file +contracts/interfaces +contracts/vendor \ No newline at end of file diff --git a/contracts/Forwarder.sol b/contracts/Forwarder.sol index 4e252660..61061bef 100644 --- a/contracts/Forwarder.sol +++ b/contracts/Forwarder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; contract Forwarder { function checker(bytes memory execData) diff --git a/contracts/Ops.sol b/contracts/Ops.sol index 8f93ce46..70cbc422 100644 --- a/contracts/Ops.sol +++ b/contracts/Ops.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity 0.8.12; -import {Gelatofied} from "./gelato/Gelatofied.sol"; -import {GelatoBytes} from "./gelato/GelatoBytes.sol"; +import {Gelatofied} from "./vendor/gelato/Gelatofied.sol"; +import {GelatoBytes} from "./vendor/gelato/GelatoBytes.sol"; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; @@ -10,7 +10,9 @@ import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import {TaskTreasury} from "./taskTreasury/TaskTreasury.sol"; +import { + ITaskTreasuryUpgradable +} from "./interfaces/ITaskTreasuryUpgradable.sol"; // solhint-disable max-line-length // solhint-disable max-states-count @@ -34,7 +36,7 @@ contract Ops is Gelatofied { mapping(bytes32 => address) public taskCreator; mapping(bytes32 => address) public execAddresses; mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks; - address public immutable taskTreasury; + ITaskTreasuryUpgradable public immutable taskTreasury; uint256 public fee; address public feeToken; // Appended State @@ -66,7 +68,7 @@ contract Ops is Gelatofied { uint128 indexed interval ); - constructor(address payable _gelato, address _taskTreasury) + constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury) Gelatofied(_gelato) { taskTreasury = _taskTreasury; @@ -117,11 +119,7 @@ contract Ops is Gelatofied { returnData.revertWithError("Ops.exec:"); if (_useTaskTreasuryFunds) { - TaskTreasury(taskTreasury).useFunds( - _feeToken, - _txFee, - _taskCreator - ); + taskTreasury.useFunds(_taskCreator, _feeToken, _txFee); } else { delete fee; delete feeToken; diff --git a/contracts/TaskTreasury/TaskTreasury.sol b/contracts/TaskTreasury/TaskTreasury.sol index 5c83c5fc..040afb9c 100644 --- a/contracts/TaskTreasury/TaskTreasury.sol +++ b/contracts/TaskTreasury/TaskTreasury.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; import { EnumerableSet @@ -13,7 +13,7 @@ import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; -import {_transfer, ETH} from "../gelato/FGelato.sol"; +import {_transfer, ETH} from "../vendor/gelato/FGelato.sol"; contract TaskTreasury is Ownable, ReentrancyGuard { using EnumerableSet for EnumerableSet.AddressSet; diff --git a/contracts/TaskTreasury/TaskTreasuryL2.sol b/contracts/TaskTreasury/TaskTreasuryL2.sol index 6e2f4303..1bdbcc65 100644 --- a/contracts/TaskTreasury/TaskTreasuryL2.sol +++ b/contracts/TaskTreasury/TaskTreasuryL2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; import { EnumerableSet @@ -13,7 +13,7 @@ import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; -import {_transfer, ETH} from "../gelato/FGelato.sol"; +import {_transfer, ETH} from "../vendor/gelato/FGelato.sol"; // solhint-disable max-states-count // solhint-disable max-line-length diff --git a/contracts/TaskTreasury/TaskTreasuryUpgradable.sol b/contracts/TaskTreasury/TaskTreasuryUpgradable.sol new file mode 100644 index 00000000..e28b84b4 --- /dev/null +++ b/contracts/TaskTreasury/TaskTreasuryUpgradable.sol @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.12; + +import { + EnumerableSet +} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import { + IERC20, + SafeERC20 +} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { + ReentrancyGuardUpgradeable +} from "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; +import { + Initializable +} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {_transfer, ETH} from "../vendor/gelato/FGelato.sol"; +import {Proxied} from "../vendor/proxy/EIP173/Proxied.sol"; +import {ITaskTreasury} from "../interfaces/ITaskTreasury.sol"; +import { + ITaskTreasuryUpgradable +} from "../interfaces/ITaskTreasuryUpgradable.sol"; +import {LibShares} from "../libraries/LibShares.sol"; + +contract TaskTreasuryUpgradable is + ITaskTreasuryUpgradable, + Proxied, + Initializable, + ReentrancyGuardUpgradeable +{ + using EnumerableSet for EnumerableSet.AddressSet; + using SafeERC20 for IERC20; + + ITaskTreasury public immutable oldTreasury; + uint256 public constant MIN_SHARES_IN_TREASURY = 1e12; + uint256 public maxFee; + + ///@dev tracks token shares of users + mapping(address => mapping(address => uint256)) public shares; + + ///@dev tracks total shares of tokens + mapping(address => uint256) public totalShares; + + ///@dev tracks the tokens deposited by users + mapping(address => EnumerableSet.AddressSet) internal _tokens; + + EnumerableSet.AddressSet internal _whitelistedServices; + + modifier onlyWhitelistedServices() { + require( + _whitelistedServices.contains(msg.sender), + "TaskTreasury: onlyWhitelistedServices" + ); + _; + } + + constructor(ITaskTreasury _oldTreasury) { + oldTreasury = _oldTreasury; + } + + receive() external payable { + depositFunds(msg.sender, ETH, msg.value); + } + + function initialize(uint256 _maxFee) external initializer { + maxFee = _maxFee; + __ReentrancyGuard_init(); + } + + /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops + /// @param _user Address of user whose balance will be deducted + /// @param _token Token to be used for payment by users + /// @param _amount Amount to be deducted + function useFunds( + address _user, + address _token, + uint256 _amount + ) external override onlyWhitelistedServices { + if (maxFee != 0) + require(maxFee >= _amount, "TaskTreasury: Overcharged"); + + uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token); + + if (_amount <= balanceInOld) { + oldTreasury.useFunds(_token, _amount, _user); + } else { + if (balanceInOld > 0) + oldTreasury.useFunds(_token, balanceInOld, _user); + + _pay(_user, _token, _amount - balanceInOld); + } + + emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender); + } + + /// @notice Change maxFee charged by Gelato (only relevant on Layer2s) + /// @param _newMaxFee New Max Fee to charge + function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin { + maxFee = _newMaxFee; + + emit UpdatedMaxFee(_newMaxFee); + } + + /// @notice Add or remove service that can call useFunds. Gelato Governance + /// @param _service Service to add or remove from whitelist + /// @param _add Add to whitelist if true, else remove from whitelist + function updateWhitelistedService(address _service, bool _add) + external + override + onlyProxyAdmin + { + if (_add) { + _whitelistedServices.add(_service); + } else { + _whitelistedServices.remove(_service); + } + + emit UpdatedService(_service, _add); + } + + /// @notice Get list of services that can call useFunds. + function getWhitelistedServices() + external + view + override + returns (address[] memory) + { + return _whitelistedServices.values(); + } + + // solhint-disable max-line-length + /// @notice Function to deposit Funds which will be used to execute transactions on various services + /// @param _receiver Address receiving the credits + /// @param _token Token to be credited, use "0xeeee...." for ETH + /// @param _amount Amount to be credited + function depositFunds( + address _receiver, + address _token, + uint256 _amount + ) public payable override nonReentrant { + uint256 depositAmount; + uint256 totalBalance; + if (_token == ETH) { + depositAmount = msg.value; + } else { + require(msg.value == 0, "TaskTreasury: No ETH"); + IERC20 token = IERC20(_token); + + uint256 preBalance = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), _amount); + uint256 postBalance = token.balanceOf(address(this)); + + depositAmount = postBalance - preBalance; + } + + totalBalance = LibShares.contractBalance(_token) - depositAmount; + + _creditUser(_receiver, _token, depositAmount, totalBalance); + + emit FundsDeposited(_receiver, _token, depositAmount); + } + + /// @notice Function to withdraw Funds back to the _receiver + /// @param _receiver Address receiving the credits + /// @param _token Token to be credited, use "0xeeee...." for ETH + /// @param _amount Amount to be credited + function withdrawFunds( + address payable _receiver, + address _token, + uint256 _amount + ) public override nonReentrant { + _deductUser(msg.sender, _token, _amount); + + _transfer(_receiver, _token, _amount); + + emit FundsWithdrawn(_receiver, msg.sender, _token, _amount); + } + + /// @notice Helper func to get all deposited tokens by a user. + /// @param _user User to get the balances from + function getCreditTokensByUser(address _user) + public + view + override + returns (address[] memory) + { + return _tokens[_user].values(); + } + + /// @notice Helper func to get all deposited tokens by a user across treasuries. + /// @param _user User to get the balances from + function getTotalCreditTokensByUser(address _user) + public + view + override + returns (address[] memory) + { + address[] memory tokensInNew = _tokens[_user].values(); + address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user); + + uint256 tokensInOldOnlyLength; + for (uint256 i; i < tokensInOld.length; i++) { + if (!_tokens[_user].contains(tokensInOld[i])) { + tokensInOld[tokensInOldOnlyLength] = tokensInOld[i]; + tokensInOldOnlyLength++; + } + } + + uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength; + address[] memory tokens = new address[](uniqTokensLength); + + for (uint256 i; i < uniqTokensLength; i++) { + if (i < tokensInNew.length) { + tokens[i] = tokensInNew[i]; + } else { + uint256 j = i - tokensInNew.length; + tokens[i] = tokensInOld[j]; + } + } + + return tokens; + } + + /// @notice Get balance of a token owned by user + /// @param _user User to get balance from + /// @param _token Token to check balance of + function userTokenBalance(address _user, address _token) + public + view + override + returns (uint256) + { + uint256 totalBalance = LibShares.contractBalance(_token); + return + LibShares.sharesToToken( + shares[_user][_token], + totalShares[_token], + totalBalance + ); + } + + /// @notice Get balance of a token owned by user across treasuries + /// @param _user User to get balance from + /// @param _token Token to check balance of + function totalUserTokenBalance(address _user, address _token) + public + view + override + returns (uint256) + { + uint256 balanceInNew = userTokenBalance(_user, _token); + uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token); + + uint256 balance = balanceInNew + balanceInOld; + + return balance; + } + + function _creditUser( + address _user, + address _token, + uint256 _amount, + uint256 _totalBalance + ) internal { + uint256 sharesTotal = totalShares[_token]; + uint256 sharesToCredit = LibShares.tokenToShares( + _token, + _amount, + sharesTotal, + _totalBalance + ); + + if (sharesTotal == 0) + require( + sharesToCredit >= MIN_SHARES_IN_TREASURY, + "TaskTreasury: Require MIN_SHARES_IN_TREASURY" + ); + + require(sharesToCredit > 0, "TaskTreasury: Zero shares to credit"); + + shares[_user][_token] += sharesToCredit; + totalShares[_token] = sharesTotal + sharesToCredit; + + _tokens[_user].add(_token); + } + + function _deductUser( + address _user, + address _token, + uint256 _amount + ) internal { + uint256 totalBalance = LibShares.contractBalance(_token); + uint256 sharesTotal = totalShares[_token]; + uint256 sharesToCharge = LibShares.tokenToShares( + _token, + _amount, + sharesTotal, + totalBalance + ); + + require( + sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY, + "TaskTreasury: Below MIN_SHARES_IN_TREASURY" + ); + + uint256 sharesOfUser = shares[_user][_token]; + + shares[_user][_token] = sharesOfUser - sharesToCharge; + totalShares[_token] = sharesTotal - sharesToCharge; + + if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token); + } + + function _pay( + address _user, + address _token, + uint256 _amount + ) internal { + address admin = _proxyAdmin(); + require(_user != admin, "TaskTreasury: No proxy admin"); + + uint256 totalBalance = LibShares.contractBalance(_token); + uint256 sharesToPay = LibShares.tokenToShares( + _token, + _amount, + totalShares[_token], + totalBalance + ); + + require( + shares[_user][_token] >= sharesToPay, + "TaskTreasury: Not enough funds" + ); + shares[_user][_token] -= sharesToPay; + shares[admin][_token] += sharesToPay; + } +} diff --git a/contracts/examples/withTreasury/Counter.sol b/contracts/examples/withTreasury/Counter.sol index 68db1c6f..c191018d 100644 --- a/contracts/examples/withTreasury/Counter.sol +++ b/contracts/examples/withTreasury/Counter.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; -import {OpsReady} from "../../gelato/OpsReady.sol"; +import {OpsReady} from "../../vendor/gelato/OpsReady.sol"; contract Counter is OpsReady { uint256 public count; diff --git a/contracts/examples/withTreasury/CounterResolver.sol b/contracts/examples/withTreasury/CounterResolver.sol index d60fb6c1..3fc91146 100644 --- a/contracts/examples/withTreasury/CounterResolver.sol +++ b/contracts/examples/withTreasury/CounterResolver.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; import {IResolver} from "../../interfaces/IResolver.sol"; diff --git a/contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol b/contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol index 410d32b6..3ffd91f2 100644 --- a/contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol +++ b/contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; import {IResolver} from "../../interfaces/IResolver.sol"; diff --git a/contracts/examples/withoutTreasury/CounterWithoutTreasury.sol b/contracts/examples/withoutTreasury/CounterWithoutTreasury.sol index a904661c..a8918c96 100644 --- a/contracts/examples/withoutTreasury/CounterWithoutTreasury.sol +++ b/contracts/examples/withoutTreasury/CounterWithoutTreasury.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; -import {OpsReady} from "../../gelato/OpsReady.sol"; +import {OpsReady} from "../../vendor/gelato/OpsReady.sol"; interface IOps { function getFeeDetails() external view returns (uint256, address); diff --git a/contracts/interfaces/IERC20Extended.sol b/contracts/interfaces/IERC20Extended.sol new file mode 100644 index 00000000..4495075a --- /dev/null +++ b/contracts/interfaces/IERC20Extended.sol @@ -0,0 +1,91 @@ +// 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 IERC20Extended { + function decimals() external view returns (uint256); + + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `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 + ); +} diff --git a/contracts/interfaces/IResolver.sol b/contracts/interfaces/IResolver.sol index 916dbbaa..4e20b1c6 100644 --- a/contracts/interfaces/IResolver.sol +++ b/contracts/interfaces/IResolver.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.0; +pragma solidity ^0.8.0; interface IResolver { function checker() diff --git a/contracts/interfaces/ITaskTreasury.sol b/contracts/interfaces/ITaskTreasury.sol new file mode 100644 index 00000000..36c6d03f --- /dev/null +++ b/contracts/interfaces/ITaskTreasury.sol @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ITaskTreasury { + /// @notice Events /// + event FundsDeposited( + address indexed sender, + address indexed token, + uint256 indexed amount + ); + + event FundsWithdrawn( + address indexed receiver, + address indexed initiator, + address indexed token, + uint256 amount + ); + + /// @notice External functions /// + + function depositFunds( + address receiver, + address token, + uint256 amount + ) external payable; + + function withdrawFunds( + address payable receiver, + address token, + uint256 amount + ) external; + + function useFunds( + address token, + uint256 amount, + address user + ) external; + + function addWhitelistedService(address service) external; + + function removeWhitelistedService(address service) external; + + /// @notice External view functions /// + + function gelato() external view returns (address); + + function getCreditTokensByUser(address user) + external + view + returns (address[] memory); + + function getWhitelistedServices() external view returns (address[] memory); + + function userTokenBalance(address user, address token) + external + view + returns (uint256); +} diff --git a/contracts/interfaces/ITaskTreasuryUpgradable.sol b/contracts/interfaces/ITaskTreasuryUpgradable.sol new file mode 100644 index 00000000..d7645909 --- /dev/null +++ b/contracts/interfaces/ITaskTreasuryUpgradable.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ITaskTreasuryUpgradable { + /// @notice Events /// + event FundsDeposited( + address indexed sender, + address indexed token, + uint256 indexed amount + ); + + event FundsWithdrawn( + address indexed receiver, + address indexed initiator, + address indexed token, + uint256 amount + ); + + event LogDeductFees( + address indexed user, + address indexed executor, + address indexed token, + uint256 fees, + address service + ); + + event UpdatedService(address indexed service, bool add); + + event UpdatedMaxFee(uint256 indexed maxFee); + + /// @notice External functions /// + + function depositFunds( + address receiver, + address token, + uint256 amount + ) external payable; + + function withdrawFunds( + address payable receiver, + address token, + uint256 amount + ) external; + + function useFunds( + address user, + address token, + uint256 amount + ) external; + + function updateMaxFee(uint256 _newMaxFee) external; + + function updateWhitelistedService(address service, bool isWhitelist) + external; + + /// @notice External view functions /// + + function getCreditTokensByUser(address user) + external + view + returns (address[] memory); + + function getTotalCreditTokensByUser(address user) + external + view + returns (address[] memory); + + function getWhitelistedServices() external view returns (address[] memory); + + function totalUserTokenBalance(address user, address token) + external + view + returns (uint256); + + function userTokenBalance(address user, address token) + external + view + returns (uint256); +} diff --git a/contracts/libraries/LibShares.sol b/contracts/libraries/LibShares.sol new file mode 100644 index 00000000..c7e4a93c --- /dev/null +++ b/contracts/libraries/LibShares.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.12; +import {ETH} from "../vendor/gelato/FGelato.sol"; +import {IERC20Extended} from "../interfaces/IERC20Extended.sol"; + +library LibShares { + function contractBalance(address _token) internal view returns (uint256) { + if (_token == ETH) { + return address(this).balance; + } else { + return IERC20Extended(_token).balanceOf(address(this)); + } + } + + function tokenToShares( + address _token, + uint256 _tokenAmount, + uint256 _totalShares, + uint256 _totalBalance + ) internal view returns (uint256) { + uint256 sharesOfToken; + + uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount); + uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance); + + // credit shares equivalent to token amount + if (_totalShares == 0 || _totalBalance == 0) { + sharesOfToken = tokenIn18Dp; + } else { + sharesOfToken = divCeil( + tokenIn18Dp * _totalShares, + totalBalanceIn18Dp + ); + } + + return sharesOfToken; + } + + function to18Dp(address _token, uint256 _amount) + internal + view + returns (uint256) + { + if (_token == ETH) return _amount; + uint256 decimals = IERC20Extended(_token).decimals(); + + if (decimals < 18) { + return _amount * 10**(18 - decimals); + } else { + return _amount / 10**(decimals - 18); + } + } + + function sharesToToken( + uint256 _shares, + uint256 _totalShares, + uint256 _totalBalance + ) internal pure returns (uint256) { + uint256 tokenOfShares; + + if (_totalShares == 0 || _totalBalance == 0) { + tokenOfShares = 0; + } else { + tokenOfShares = (_shares * _totalBalance) / _totalShares; + } + + return tokenOfShares; + } + + function divCeil(uint256 x, uint256 y) internal pure returns (uint256) { + uint256 remainder = x % y; + uint256 result; + + if (remainder == 0) { + result = x / y; + } else { + result = ((x - remainder) + y) / y; + } + + return result; + } +} diff --git a/contracts/mocks/CounterTimedTask.sol b/contracts/mocks/CounterTimedTask.sol index 92e84a31..f8c72a99 100644 --- a/contracts/mocks/CounterTimedTask.sol +++ b/contracts/mocks/CounterTimedTask.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.0; -import {OpsReady} from "../gelato/OpsReady.sol"; +import {OpsReady} from "../vendor/gelato/OpsReady.sol"; contract CounterTimedTask is OpsReady { uint256 public count; diff --git a/contracts/Gelato/FGelato.sol b/contracts/vendor/gelato/FGelato.sol similarity index 96% rename from contracts/Gelato/FGelato.sol rename to contracts/vendor/gelato/FGelato.sol index 4569bf8b..e3c0562b 100644 --- a/contracts/Gelato/FGelato.sol +++ b/contracts/vendor/gelato/FGelato.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.12; import { SafeERC20, diff --git a/contracts/Gelato/GelatoBytes.sol b/contracts/vendor/gelato/GelatoBytes.sol similarity index 97% rename from contracts/Gelato/GelatoBytes.sol rename to contracts/vendor/gelato/GelatoBytes.sol index d430d156..5136b07f 100644 --- a/contracts/Gelato/GelatoBytes.sol +++ b/contracts/vendor/gelato/GelatoBytes.sol @@ -1,5 +1,5 @@ -// "SPDX-License-Identifier: UNLICENSED" -pragma solidity 0.8.0; +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.12; library GelatoBytes { function calldataSliceSelector(bytes calldata _bytes) diff --git a/contracts/Gelato/Gelatofied.sol b/contracts/vendor/gelato/Gelatofied.sol similarity index 96% rename from contracts/Gelato/Gelatofied.sol rename to contracts/vendor/gelato/Gelatofied.sol index d0ddff86..ffb80acb 100644 --- a/contracts/Gelato/Gelatofied.sol +++ b/contracts/vendor/gelato/Gelatofied.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.12; import { SafeERC20, diff --git a/contracts/Gelato/OpsReady.sol b/contracts/vendor/gelato/OpsReady.sol similarity index 97% rename from contracts/Gelato/OpsReady.sol rename to contracts/vendor/gelato/OpsReady.sol index 7b140431..171b23d4 100644 --- a/contracts/Gelato/OpsReady.sol +++ b/contracts/vendor/gelato/OpsReady.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.0; +pragma solidity ^0.8.12; import { SafeERC20, diff --git a/contracts/vendor/proxy/EIP173/EIP173Proxy.sol b/contracts/vendor/proxy/EIP173/EIP173Proxy.sol new file mode 100644 index 00000000..ec056246 --- /dev/null +++ b/contracts/vendor/proxy/EIP173/EIP173Proxy.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import "./Proxy.sol"; + +interface ERC165 { + function supportsInterface(bytes4 id) external view returns (bool); +} + +///@notice Proxy implementing EIP173 for ownership management +contract EIP173Proxy is Proxy { + // ////////////////////////// EVENTS /////////////////////////////////////////////////////////////////////// + + event ProxyAdminTransferred( + address indexed previousAdmin, + address indexed newAdmin + ); + + // /////////////////////// CONSTRUCTOR ////////////////////////////////////////////////////////////////////// + + constructor( + address implementationAddress, + address adminAddress, + bytes memory data + ) payable { + _setImplementation(implementationAddress, data); + _setProxyAdmin(adminAddress); + } + + // ///////////////////// EXTERNAL /////////////////////////////////////////////////////////////////////////// + + function proxyAdmin() external view returns (address) { + return _proxyAdmin(); + } + + function supportsInterface(bytes4 id) external view returns (bool) { + if (id == 0x01ffc9a7 || id == 0x7f5828d0) { + return true; + } + if (id == 0xFFFFFFFF) { + return false; + } + + ERC165 implementation; + // solhint-disable-next-line security/no-inline-assembly + assembly { + implementation := sload( + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc + ) + } + + // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure + // because it is itself inside `supportsInterface` that might only get 30,000 gas. + // In practise this is unlikely to be an issue. + try implementation.supportsInterface(id) returns (bool support) { + return support; + } catch { + return false; + } + } + + function transferProxyAdmin(address newAdmin) external onlyProxyAdmin { + _setProxyAdmin(newAdmin); + } + + function upgradeTo(address newImplementation) external onlyProxyAdmin { + _setImplementation(newImplementation, ""); + } + + function upgradeToAndCall(address newImplementation, bytes calldata data) + external + payable + onlyProxyAdmin + { + _setImplementation(newImplementation, data); + } + + // /////////////////////// MODIFIERS //////////////////////////////////////////////////////////////////////// + + modifier onlyProxyAdmin() { + require(msg.sender == _proxyAdmin(), "NOT_AUTHORIZED"); + _; + } + + // ///////////////////////// INTERNAL ////////////////////////////////////////////////////////////////////// + + function _proxyAdmin() internal view returns (address adminAddress) { + // solhint-disable-next-line security/no-inline-assembly + assembly { + adminAddress := sload( + 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 + ) + } + } + + function _setProxyAdmin(address newAdmin) internal { + address previousAdmin = _proxyAdmin(); + // solhint-disable-next-line security/no-inline-assembly + assembly { + sstore( + 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, + newAdmin + ) + } + emit ProxyAdminTransferred(previousAdmin, newAdmin); + } +} diff --git a/contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol b/contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol new file mode 100644 index 00000000..62f29ddc --- /dev/null +++ b/contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import "./EIP173Proxy.sol"; + +///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive +contract EIP173ProxyWithCustomReceive is EIP173Proxy { + constructor( + address implementationAddress, + address ownerAddress, + bytes memory data + ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {} + + receive() external payable override { + _fallback(); + } +} diff --git a/contracts/vendor/proxy/EIP173/Proxied.sol b/contracts/vendor/proxy/EIP173/Proxied.sol new file mode 100644 index 00000000..7590f60b --- /dev/null +++ b/contracts/vendor/proxy/EIP173/Proxied.sol @@ -0,0 +1,44 @@ +// 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 + ) + } + } +} diff --git a/contracts/vendor/proxy/EIP173/Proxy.sol b/contracts/vendor/proxy/EIP173/Proxy.sol new file mode 100644 index 00000000..8bfb4045 --- /dev/null +++ b/contracts/vendor/proxy/EIP173/Proxy.sol @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +// EIP-1967 +abstract contract Proxy { + // /////////////////////// EVENTS /////////////////////////////////////////////////////////////////////////// + + event ProxyImplementationUpdated( + address indexed previousImplementation, + address indexed newImplementation + ); + + // ///////////////////// EXTERNAL /////////////////////////////////////////////////////////////////////////// + + // prettier-ignore + receive() external payable virtual { + revert("ETHER_REJECTED"); // explicit reject by default + } + + fallback() external payable { + _fallback(); + } + + // ///////////////////////// INTERNAL ////////////////////////////////////////////////////////////////////// + + function _fallback() internal { + // solhint-disable-next-line security/no-inline-assembly + assembly { + let implementationAddress := sload( + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc + ) + calldatacopy(0x0, 0x0, calldatasize()) + let success := delegatecall( + gas(), + implementationAddress, + 0x0, + calldatasize(), + 0, + 0 + ) + let retSz := returndatasize() + returndatacopy(0, 0, retSz) + switch success + case 0 { + revert(0, retSz) + } + default { + return(0, retSz) + } + } + } + + function _setImplementation(address newImplementation, bytes memory data) + internal + { + address previousImplementation; + // solhint-disable-next-line security/no-inline-assembly + assembly { + previousImplementation := sload( + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc + ) + } + + // solhint-disable-next-line security/no-inline-assembly + assembly { + sstore( + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, + newImplementation + ) + } + + emit ProxyImplementationUpdated( + previousImplementation, + newImplementation + ); + + if (data.length > 0) { + (bool success, ) = newImplementation.delegatecall(data); + if (!success) { + assembly { + // This assembly ensure the revert contains the exact string data + let returnDataSize := returndatasize() + returndatacopy(0, 0, returnDataSize) + revert(0, returnDataSize) + } + } + } + } +} diff --git a/deploy/Ops.deploy.js b/deploy/Ops.deploy.js index e1de8b9f..0a00b72f 100644 --- a/deploy/Ops.deploy.js +++ b/deploy/Ops.deploy.js @@ -17,9 +17,10 @@ module.exports = async (hre) => { proxy: { owner: deployer, }, - // IMPORTANT: FOR FANTOM AND POLYGON HARDCODE THE ADDRESS - // (await hre.ethers.getContract("TaskTreasuryFantom")).address, - args: [GELATO, (await hre.ethers.getContract("TaskTreasury")).address], + args: [ + GELATO, + (await hre.ethers.getContract("TaskTreasuryUpgradable")).address, + ], }); }; @@ -29,5 +30,4 @@ module.exports.skip = async (hre) => { }; module.exports.tags = ["Ops"]; -// Comment out if deploy to Fantom or Matic -module.exports.dependencies = ["TaskTreasury"]; +module.exports.dependencies = ["TaskTreasuryUpgradable"]; diff --git a/deploy/TaskTreasuryUpgradable.deploy.js b/deploy/TaskTreasuryUpgradable.deploy.js new file mode 100644 index 00000000..e76528fd --- /dev/null +++ b/deploy/TaskTreasuryUpgradable.deploy.js @@ -0,0 +1,44 @@ +const { sleep } = require("@gelatonetwork/core"); +const { getOldTaskTreasuryAddress } = require("../hardhat/config/addresses"); +const { getMaxFee } = require("../hardhat/config/maxFee"); + +module.exports = async (hre) => { + const taskTreasuryAddress = getOldTaskTreasuryAddress(hre.network.name); + const maxFee = getMaxFee(hre.network.name); // NOTE: Check max fee before deploying + + if (hre.network.name !== "hardhat") { + console.log( + `Deploying TaskTreasuryUpgradable to ${hre.network.name}. Hit ctrl + c to abort` + ); + console.log(`Using Old TaskTreasury: ${taskTreasuryAddress}`); + console.log(`Max fee: ${maxFee}`); + await sleep(10000); + } + + const { deployments } = hre; + const { deploy } = deployments; + const { deployer } = await hre.getNamedAccounts(); + + await deploy("TaskTreasuryUpgradable", { + from: deployer, + proxy: { + proxyContract: "EIP173ProxyWithCustomReceive", + owner: deployer, + execute: { + init: { + methodName: "initialize", + args: [maxFee], + }, + }, + }, + args: [taskTreasuryAddress], + log: hre.network.name !== "hardhat" ? true : false, + }); +}; + +module.exports.skip = async (hre) => { + const skip = hre.network.name !== "hardhat"; + return skip ? true : false; +}; + +module.exports.tags = ["TaskTreasuryUpgradable"]; diff --git a/deployments/arbitrum/Ops.json b/deployments/arbitrum/Ops.json index 46ce863b..dfb82d89 100644 --- a/deployments/arbitrum/Ops.json +++ b/deployments/arbitrum/Ops.json @@ -1582,7 +1582,7 @@ } } ], - "implementation": "0xd76a1c8589d14030a52Ce44Eb4Db7d7BaeaEb2D5", + "implementation": "0xc354a35F98574C76b93FcD0633724AAd66b0613b", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/arbitrum/Ops_Implementation.json b/deployments/arbitrum/Ops_Implementation.json index 01a3f68d..d5ff40d1 100644 --- a/deployments/arbitrum/Ops_Implementation.json +++ b/deployments/arbitrum/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xd76a1c8589d14030a52Ce44Eb4Db7d7BaeaEb2D5", + "address": "0xc354a35F98574C76b93FcD0633724AAd66b0613b", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0x6afa7af748548d7ec6be01e1a72c67b16bfbe2ec29679ab0119ce320867de3b0", + "transactionHash": "0xdf6da938f738b183ca61a82b11e0c6f91838337cb600a72169ae94e87d9e82fe", "receipt": { "to": null, "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", - "contractAddress": "0xd76a1c8589d14030a52Ce44Eb4Db7d7BaeaEb2D5", + "contractAddress": "0xc354a35F98574C76b93FcD0633724AAd66b0613b", "transactionIndex": 0, - "gasUsed": "40657480", + "gasUsed": "41367028", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x0492a49371326c4bbd909de5d5a01feb38d08b5bf253904f02e671b15001fbc1", - "transactionHash": "0x6afa7af748548d7ec6be01e1a72c67b16bfbe2ec29679ab0119ce320867de3b0", + "blockHash": "0x97651d0e5080b1fa8eb21af33723dab7df2a4ab6de72ef1178260c4d42adc998", + "transactionHash": "0xdf6da938f738b183ca61a82b11e0c6f91838337cb600a72169ae94e87d9e82fe", "logs": [], - "blockNumber": 5421346, - "cumulativeGasUsed": "19160300", + "blockNumber": 9718142, + "cumulativeGasUsed": "19323368", "status": 1, "byzantium": true }, "args": [ "0x4775aF8FEf4809fE10bf05867d2b038a4b5B2146", - "0x527a819db1eb0e34426297b03bae11F2f8B3A19E" + "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/arbitrum/TaskTreasuryUpgradable.json b/deployments/arbitrum/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..7f70189e --- /dev/null +++ b/deployments/arbitrum/TaskTreasuryUpgradable.json @@ -0,0 +1,647 @@ +{ + "address": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "transactionIndex": 0, + "gasUsed": "12152877", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000080000000000400000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000900000001010000000000000000000000000000020000000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0x4b6382864687472a84e6618adbb5f3e49abd4324d201551c64d0cb441173f208", + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9717973, + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "address": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000fbaa1c060dfa2e274e8117f8e497b537fa520704" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x4b6382864687472a84e6618adbb5f3e49abd4324d201551c64d0cb441173f208" + }, + { + "transactionIndex": 0, + "blockNumber": 9717973, + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "address": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x4b6382864687472a84e6618adbb5f3e49abd4324d201551c64d0cb441173f208" + } + ], + "blockNumber": 9717973, + "cumulativeGasUsed": "4634637", + "status": 1, + "byzantium": true + }, + "args": [ + "0xfBaA1c060dFa2E274E8117f8e497b537fA520704", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df000000000000000000000000000000000000000000000000002386f26fc10000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x2386f26fc10000" + } + ] + }, + "implementation": "0xfBaA1c060dFa2E274E8117f8e497b537fA520704", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/arbitrum/TaskTreasuryUpgradable_Implementation.json b/deployments/arbitrum/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..5ef965b8 --- /dev/null +++ b/deployments/arbitrum/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,749 @@ +{ + "address": "0xfBaA1c060dFa2E274E8117f8e497b537fA520704", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb5172a298c875a10058b30a810011406c3df2caffd06754b3b34245e9d5096f0", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xfBaA1c060dFa2E274E8117f8e497b537fA520704", + "transactionIndex": 0, + "gasUsed": "50461106", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xbf94f37fb5a85b1832d7995f933b419f9bc78b6f255a4e9f2edd55e1bf749a43", + "transactionHash": "0xb5172a298c875a10058b30a810011406c3df2caffd06754b3b34245e9d5096f0", + "logs": [], + "blockNumber": 9717968, + "cumulativeGasUsed": "23925086", + "status": 1, + "byzantium": true + }, + "args": ["0x527a819db1eb0e34426297b03bae11F2f8B3A19E"], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/arbitrum/TaskTreasuryUpgradable_Proxy.json b/deployments/arbitrum/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..0c85c55f --- /dev/null +++ b/deployments/arbitrum/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,218 @@ +{ + "address": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "transactionIndex": 0, + "gasUsed": "12152877", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000080000000000400000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000900000001010000000000000000000000000000020000000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0x4b6382864687472a84e6618adbb5f3e49abd4324d201551c64d0cb441173f208", + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9717973, + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "address": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000fbaa1c060dfa2e274e8117f8e497b537fa520704" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x4b6382864687472a84e6618adbb5f3e49abd4324d201551c64d0cb441173f208" + }, + { + "transactionIndex": 0, + "blockNumber": 9717973, + "transactionHash": "0x6918c29e6c56b6393be0b25588e3ed20feb76c6084d38ae7f93d00d4ce9fa531", + "address": "0xB2f34fd4C16e656163dADFeEaE4Ae0c1F13b140A", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x4b6382864687472a84e6618adbb5f3e49abd4324d201551c64d0cb441173f208" + } + ], + "blockNumber": 9717973, + "cumulativeGasUsed": "4634637", + "status": 1, + "byzantium": true + }, + "args": [ + "0xfBaA1c060dFa2E274E8117f8e497b537fA520704", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df000000000000000000000000000000000000000000000000002386f26fc10000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/arbitrum/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/arbitrum/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/arbitrum/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/avalanche/Ops.json b/deployments/avalanche/Ops.json index 2fe9cba9..309e6e08 100644 --- a/deployments/avalanche/Ops.json +++ b/deployments/avalanche/Ops.json @@ -1582,7 +1582,7 @@ } } ], - "implementation": "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "implementation": "0x1896784b332071804A134263e3340411d3cdA9D2", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/avalanche/Ops_Implementation.json b/deployments/avalanche/Ops_Implementation.json index ac00e57f..22ae1163 100644 --- a/deployments/avalanche/Ops_Implementation.json +++ b/deployments/avalanche/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "address": "0x1896784b332071804A134263e3340411d3cdA9D2", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0xa958af8e6c653a4940a8d3820f31b8cd2b984ac78876cfd6f3db2051f850ca70", + "transactionHash": "0xd331054c567029e72fda868f28c9697672a796175b34c033d059574ae966280d", "receipt": { "to": null, "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", - "contractAddress": "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", - "transactionIndex": 13, - "gasUsed": "2650216", + "contractAddress": "0x1896784b332071804A134263e3340411d3cdA9D2", + "transactionIndex": 15, + "gasUsed": "2673374", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe9ffb0770d1351c2567882316ac9d2d7575c74cd3bb2a6c5833dffe326ad9dc3", - "transactionHash": "0xa958af8e6c653a4940a8d3820f31b8cd2b984ac78876cfd6f3db2051f850ca70", + "blockHash": "0x7571eb46a6a288715229c3e9d0cc0eb79502143a9ff40b8d2850c42d52b50bca", + "transactionHash": "0xd331054c567029e72fda868f28c9697672a796175b34c033d059574ae966280d", "logs": [], - "blockNumber": 10477565, - "cumulativeGasUsed": "4307965", + "blockNumber": 13309333, + "cumulativeGasUsed": "6091374", "status": 1, "byzantium": true }, "args": [ "0x7C5c4Af1618220C090A6863175de47afb20fa9Df", - "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb" + "0xe167199A490b04042414aFD71830bBF165f44C09" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/avalanche/TaskTreasuryUpgradable.json b/deployments/avalanche/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..6ae974b8 --- /dev/null +++ b/deployments/avalanche/TaskTreasuryUpgradable.json @@ -0,0 +1,646 @@ +{ + "address": "0xe167199A490b04042414aFD71830bBF165f44C09", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xe167199A490b04042414aFD71830bBF165f44C09", + "transactionIndex": 18, + "gasUsed": "782874", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000020000000000000000000000010000000000000000080000000000020000000000000000000000400200000010002000000000000010000000000000000", + "blockHash": "0xb6b6046e3391704159705606d5f2c4533f237db8fe3109210b7057efac1abb9b", + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "logs": [ + { + "transactionIndex": 18, + "blockNumber": 13101499, + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "address": "0xe167199A490b04042414aFD71830bBF165f44C09", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000007cf9a9bce6238f5c27c835b9666f763aadaf686c" + ], + "data": "0x", + "logIndex": 86, + "blockHash": "0xb6b6046e3391704159705606d5f2c4533f237db8fe3109210b7057efac1abb9b" + }, + { + "transactionIndex": 18, + "blockNumber": 13101499, + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "address": "0xe167199A490b04042414aFD71830bBF165f44C09", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 87, + "blockHash": "0xb6b6046e3391704159705606d5f2c4533f237db8fe3109210b7057efac1abb9b" + } + ], + "blockNumber": 13101499, + "cumulativeGasUsed": "6080714", + "status": 1, + "byzantium": true + }, + "args": [ + "0x7cF9a9BcE6238f5C27C835b9666F763aADaF686c", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000001bc16d674ec80000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x1bc16d674ec80000" + } + ] + }, + "implementation": "0x7cF9a9BcE6238f5C27C835b9666F763aADaF686c", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/avalanche/TaskTreasuryUpgradable_Implementation.json b/deployments/avalanche/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..3d75eab2 --- /dev/null +++ b/deployments/avalanche/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,748 @@ +{ + "address": "0x7cF9a9BcE6238f5C27C835b9666F763aADaF686c", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x86e8e72cdae66f003260a2a3706527414157ab64a1eef5c66fca7b4f5bd40c63", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x7cF9a9BcE6238f5C27C835b9666F763aADaF686c", + "transactionIndex": 9, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1e902a4d2b8f552c1a6b99475230f4996ab2b709151df9670a9bc97095524006", + "transactionHash": "0x86e8e72cdae66f003260a2a3706527414157ab64a1eef5c66fca7b4f5bd40c63", + "logs": [], + "blockNumber": 13101487, + "cumulativeGasUsed": "4631116", + "status": 1, + "byzantium": true + }, + "args": ["0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/avalanche/TaskTreasuryUpgradable_Proxy.json b/deployments/avalanche/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..c769b40f --- /dev/null +++ b/deployments/avalanche/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,217 @@ +{ + "address": "0xe167199A490b04042414aFD71830bBF165f44C09", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xe167199A490b04042414aFD71830bBF165f44C09", + "transactionIndex": 18, + "gasUsed": "782874", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000020000000000000000000000010000000000000000080000000000020000000000000000000000400200000010002000000000000010000000000000000", + "blockHash": "0xb6b6046e3391704159705606d5f2c4533f237db8fe3109210b7057efac1abb9b", + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "logs": [ + { + "transactionIndex": 18, + "blockNumber": 13101499, + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "address": "0xe167199A490b04042414aFD71830bBF165f44C09", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000007cf9a9bce6238f5c27c835b9666f763aadaf686c" + ], + "data": "0x", + "logIndex": 86, + "blockHash": "0xb6b6046e3391704159705606d5f2c4533f237db8fe3109210b7057efac1abb9b" + }, + { + "transactionIndex": 18, + "blockNumber": 13101499, + "transactionHash": "0xdc2b241818ca8bdc8763b2b1c374be2041a12430838b476dda735ce20830c1ff", + "address": "0xe167199A490b04042414aFD71830bBF165f44C09", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 87, + "blockHash": "0xb6b6046e3391704159705606d5f2c4533f237db8fe3109210b7057efac1abb9b" + } + ], + "blockNumber": 13101499, + "cumulativeGasUsed": "6080714", + "status": 1, + "byzantium": true + }, + "args": [ + "0x7cF9a9BcE6238f5C27C835b9666F763aADaF686c", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000001bc16d674ec80000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/avalanche/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/avalanche/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/avalanche/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/bsc/Ops.json b/deployments/bsc/Ops.json index 949cff13..9c34f2a6 100644 --- a/deployments/bsc/Ops.json +++ b/deployments/bsc/Ops.json @@ -1582,7 +1582,7 @@ } } ], - "implementation": "0x22Afd4272F61FD0451C66A4F08516969EFCAef00", + "implementation": "0x1ED0f2a7aa7Be83d411C3934925460A08385690C", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/bsc/Ops_Implementation.json b/deployments/bsc/Ops_Implementation.json index ca7e772a..bbb99586 100644 --- a/deployments/bsc/Ops_Implementation.json +++ b/deployments/bsc/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x22Afd4272F61FD0451C66A4F08516969EFCAef00", + "address": "0x1ED0f2a7aa7Be83d411C3934925460A08385690C", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0xc4714093dcf9f272f40d89c60250e57dddb5a14683a6b2495b325c95fcaab4dd", + "transactionHash": "0x627aebdb98000dd67a9183614b0abe7e15de1d5f62e26d633af952d0e186d968", "receipt": { "to": null, "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", - "contractAddress": "0x22Afd4272F61FD0451C66A4F08516969EFCAef00", - "transactionIndex": 52, - "gasUsed": "2650216", + "contractAddress": "0x1ED0f2a7aa7Be83d411C3934925460A08385690C", + "transactionIndex": 68, + "gasUsed": "2673374", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa9d07a4f684a6cae953b41109dcf365dc45482e725879ae4932274e0753a3a4c", - "transactionHash": "0xc4714093dcf9f272f40d89c60250e57dddb5a14683a6b2495b325c95fcaab4dd", + "blockHash": "0xc40621116d568262c14377b99bb1a4e7270864281e0fec9bca558842c366defb", + "transactionHash": "0x627aebdb98000dd67a9183614b0abe7e15de1d5f62e26d633af952d0e186d968", "logs": [], - "blockNumber": 14962701, - "cumulativeGasUsed": "6383932", + "blockNumber": 16872642, + "cumulativeGasUsed": "15422611", "status": 1, "byzantium": true }, "args": [ "0x7C5c4Af1618220C090A6863175de47afb20fa9Df", - "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb" + "0xbECe6A2101eC94E817c072622671B399A3508Ac1" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/bsc/TaskTreasuryUpgradable.json b/deployments/bsc/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..43d7baec --- /dev/null +++ b/deployments/bsc/TaskTreasuryUpgradable.json @@ -0,0 +1,646 @@ +{ + "address": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "transactionIndex": 195, + "gasUsed": "779162", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000402000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000020000000010000000000800000000000000000000000000000000000100000000000000200000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000000000010000000000000000000000000000020000000080000000000000400000000000002000000000000010000000000000000", + "blockHash": "0xe73d08cb714a25bf9092cbce87b4cd2e73f5c426661be7b551be39f3a3348b49", + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "logs": [ + { + "transactionIndex": 195, + "blockNumber": 16732609, + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "address": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000d167afcee4e9a89e69646fd3c27e58b61d1b7f97" + ], + "data": "0x", + "logIndex": 539, + "blockHash": "0xe73d08cb714a25bf9092cbce87b4cd2e73f5c426661be7b551be39f3a3348b49" + }, + { + "transactionIndex": 195, + "blockNumber": 16732609, + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "address": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 540, + "blockHash": "0xe73d08cb714a25bf9092cbce87b4cd2e73f5c426661be7b551be39f3a3348b49" + } + ], + "blockNumber": 16732609, + "cumulativeGasUsed": "21892491", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD167afcEE4E9A89e69646fd3C27e58b61d1b7f97", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df000000000000000000000000000000000000000000000000002386f26fc10000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x2386f26fc10000" + } + ] + }, + "implementation": "0xD167afcEE4E9A89e69646fd3C27e58b61d1b7f97", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsc/TaskTreasuryUpgradable_Implementation.json b/deployments/bsc/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..ddb423de --- /dev/null +++ b/deployments/bsc/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,748 @@ +{ + "address": "0xD167afcEE4E9A89e69646fd3C27e58b61d1b7f97", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xfd142054f8831a8c95edbd07c62ac82075842bbc1e9b4f92aee0d98bd82bd4ee", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xD167afcEE4E9A89e69646fd3C27e58b61d1b7f97", + "transactionIndex": 77, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd195dfd85910de8a61b7fc4ff87e1e7ee922229200c709f37f2dd11782fb7f80", + "transactionHash": "0xfd142054f8831a8c95edbd07c62ac82075842bbc1e9b4f92aee0d98bd82bd4ee", + "logs": [], + "blockNumber": 16732606, + "cumulativeGasUsed": "10784195", + "status": 1, + "byzantium": true + }, + "args": ["0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/bsc/TaskTreasuryUpgradable_Proxy.json b/deployments/bsc/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..37bd6665 --- /dev/null +++ b/deployments/bsc/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,217 @@ +{ + "address": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "transactionIndex": 195, + "gasUsed": "779162", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000402000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000020000000010000000000800000000000000000000000000000000000100000000000000200000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000000000010000000000000000000000000000020000000080000000000000400000000000002000000000000010000000000000000", + "blockHash": "0xe73d08cb714a25bf9092cbce87b4cd2e73f5c426661be7b551be39f3a3348b49", + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "logs": [ + { + "transactionIndex": 195, + "blockNumber": 16732609, + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "address": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000d167afcee4e9a89e69646fd3c27e58b61d1b7f97" + ], + "data": "0x", + "logIndex": 539, + "blockHash": "0xe73d08cb714a25bf9092cbce87b4cd2e73f5c426661be7b551be39f3a3348b49" + }, + { + "transactionIndex": 195, + "blockNumber": 16732609, + "transactionHash": "0x03fea9cf2ed27df8d0afd8d7feab4e5c445d7a3c4d8a91e52e47dd7e73f73f31", + "address": "0xbECe6A2101eC94E817c072622671B399A3508Ac1", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 540, + "blockHash": "0xe73d08cb714a25bf9092cbce87b4cd2e73f5c426661be7b551be39f3a3348b49" + } + ], + "blockNumber": 16732609, + "cumulativeGasUsed": "21892491", + "status": 1, + "byzantium": true + }, + "args": [ + "0xD167afcEE4E9A89e69646fd3C27e58b61d1b7f97", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df000000000000000000000000000000000000000000000000002386f26fc10000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/bsc/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/bsc/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/bsc/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/fantom/Ops.json b/deployments/fantom/Ops.json index 7336bc05..e54471f7 100644 --- a/deployments/fantom/Ops.json +++ b/deployments/fantom/Ops.json @@ -2956,7 +2956,7 @@ } } ], - "implementation": "0xAdf52B8027beb2CC35250d8CE9d2ea1Ef177e1Cc", + "implementation": "0xc31F344E149Cb9a247Ff2AdB9Eb1a594fA7BAe47", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/fantom/Ops_Implementation.json b/deployments/fantom/Ops_Implementation.json index 31b6b0b5..d2dc7622 100644 --- a/deployments/fantom/Ops_Implementation.json +++ b/deployments/fantom/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xAdf52B8027beb2CC35250d8CE9d2ea1Ef177e1Cc", + "address": "0xc31F344E149Cb9a247Ff2AdB9Eb1a594fA7BAe47", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0x4f9fc9b42710847e0e1dcee00cd643f85e0c1b1f296affc29068e931704238a6", + "transactionHash": "0xc175e00bf16c6f654080a3878ee77e92f038abb71855ebad9984d42dfc4098c2", "receipt": { "to": null, - "from": "0xAabB54394E8dd61Dd70897E9c80be8de7C64A895", - "contractAddress": "0xAdf52B8027beb2CC35250d8CE9d2ea1Ef177e1Cc", - "transactionIndex": 21, - "gasUsed": "2650204", + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xc31F344E149Cb9a247Ff2AdB9Eb1a594fA7BAe47", + "transactionIndex": 0, + "gasUsed": "2673374", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x00013286000000a935914261bc82b881f3c447a8b08cda2136fc772656940f51", - "transactionHash": "0x4f9fc9b42710847e0e1dcee00cd643f85e0c1b1f296affc29068e931704238a6", + "blockHash": "0x00018ead0000109efa8a605fa84c8788bb54cc3ec34b79ca104b78a5109cdcfb", + "transactionHash": "0xc175e00bf16c6f654080a3878ee77e92f038abb71855ebad9984d42dfc4098c2", "logs": [], - "blockNumber": 29990728, - "cumulativeGasUsed": "4639243", + "blockNumber": 35851732, + "cumulativeGasUsed": "2673374", "status": 1, "byzantium": true }, "args": [ "0xebA27A2301975FF5BF7864b99F55A4f7A457ED10", - "0x6c3224f9b3feE000A444681d5D45e4532D5BA531" + "0x0af13072280E10907911ce5d046c2DfA1B604d23" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/fantom/TaskTreasuryUpgradable.json b/deployments/fantom/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..3e995d52 --- /dev/null +++ b/deployments/fantom/TaskTreasuryUpgradable.json @@ -0,0 +1,646 @@ +{ + "address": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "transactionIndex": 5, + "gasUsed": "779186", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000020000000000000000000800000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000040000010000000000000000000000000000020000000000000000000000400000000040002000000000040010000000000000000", + "blockHash": "0x000188c700000e024d532f9d8efe6b3df2d4331f365db092806d77bcc1433e42", + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 35445015, + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "address": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002dbcd72a48f5639afc76259b85aff339c1b6e646" + ], + "data": "0x", + "logIndex": 17, + "blockHash": "0x000188c700000e024d532f9d8efe6b3df2d4331f365db092806d77bcc1433e42" + }, + { + "transactionIndex": 5, + "blockNumber": 35445015, + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "address": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 18, + "blockHash": "0x000188c700000e024d532f9d8efe6b3df2d4331f365db092806d77bcc1433e42" + } + ], + "blockNumber": 35445015, + "cumulativeGasUsed": "1339590", + "status": 1, + "byzantium": true + }, + "args": [ + "0x2DBCD72A48F5639afc76259b85aff339c1B6E646", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df000000000000000000000000000000000000000000000002b5e3af16b1880000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x02b5e3af16b1880000" + } + ] + }, + "implementation": "0x2DBCD72A48F5639afc76259b85aff339c1B6E646", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/fantom/TaskTreasuryUpgradable_Implementation.json b/deployments/fantom/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..9818f69d --- /dev/null +++ b/deployments/fantom/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,748 @@ +{ + "address": "0x2DBCD72A48F5639afc76259b85aff339c1B6E646", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x58c213e64233d93c514474e610bbdac297b87680568549925f63035be2eb8317", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x2DBCD72A48F5639afc76259b85aff339c1B6E646", + "transactionIndex": 1, + "gasUsed": "3294701", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x000188c700000dbff46b17c10750410e92210195fc67082cbfb02d56eb16dd6a", + "transactionHash": "0x58c213e64233d93c514474e610bbdac297b87680568549925f63035be2eb8317", + "logs": [], + "blockNumber": 35445010, + "cumulativeGasUsed": "4111998", + "status": 1, + "byzantium": true + }, + "args": ["0x6c3224f9b3feE000A444681d5D45e4532D5BA531"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/fantom/TaskTreasuryUpgradable_Proxy.json b/deployments/fantom/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..f2606620 --- /dev/null +++ b/deployments/fantom/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,217 @@ +{ + "address": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "transactionIndex": 5, + "gasUsed": "779186", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000020000000000000000000800000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000040000010000000000000000000000000000020000000000000000000000400000000040002000000000040010000000000000000", + "blockHash": "0x000188c700000e024d532f9d8efe6b3df2d4331f365db092806d77bcc1433e42", + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 35445015, + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "address": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000002dbcd72a48f5639afc76259b85aff339c1b6e646" + ], + "data": "0x", + "logIndex": 17, + "blockHash": "0x000188c700000e024d532f9d8efe6b3df2d4331f365db092806d77bcc1433e42" + }, + { + "transactionIndex": 5, + "blockNumber": 35445015, + "transactionHash": "0x34a994b330df7674fa2b1bb0320ceb92c9e21fc974d30f03c195e788271c4b8d", + "address": "0x0af13072280E10907911ce5d046c2DfA1B604d23", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 18, + "blockHash": "0x000188c700000e024d532f9d8efe6b3df2d4331f365db092806d77bcc1433e42" + } + ], + "blockNumber": 35445015, + "cumulativeGasUsed": "1339590", + "status": 1, + "byzantium": true + }, + "args": [ + "0x2DBCD72A48F5639afc76259b85aff339c1B6E646", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df000000000000000000000000000000000000000000000002b5e3af16b1880000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/fantom/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/fantom/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/fantom/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/gnosis/Ops.json b/deployments/gnosis/Ops.json index ddc8de9a..f4b8b3ec 100644 --- a/deployments/gnosis/Ops.json +++ b/deployments/gnosis/Ops.json @@ -665,7 +665,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -782,11 +782,12 @@ "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", "0x" ], - "solcInputHash": "2db89642daf7ebd20cbbef9f4540b20d", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.7/proxy/EIP173Proxy.sol\":\"EIP173Proxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.7/proxy/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setOwner(ownerAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function owner() external view returns (address) {\\n return _owner();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferOwnership(address newOwner) external onlyOwner {\\n _setOwner(newOwner);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyOwner {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyOwner() {\\n require(msg.sender == _owner(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _owner() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\\n }\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address previousOwner = _owner();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\\n }\\n emit OwnershipTransferred(previousOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7f9bbb686cd29ade05acf0cec1bfded16f0ad8d7e3fcb9cf35cc8b04efdda744\",\"license\":\"MIT\"},\"solc_0.7/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data) internal {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\\n }\\n\\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfa071ffed5c967384ac4787576322a46a4863d89bf39cd6fde58d4780b42e0ed\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6080604052604051610bed380380610bed8339818101604052606081101561002657600080fd5b8151602083015160408085018051915193959294830192918464010000000082111561005157600080fd5b90830190602082018581111561006657600080fd5b825164010000000081118282018810171561008057600080fd5b82525081516020918201929091019080838360005b838110156100ad578181015183820152602001610095565b50505050905090810190601f1680156100da5780820380516001836020036101000a031916815260200191505b506040525050506100f1838261010260201b60201c565b6100fa82610225565b505050610299565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8054908390556040516001600160a01b0380851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a3815115610220576000836001600160a01b0316836040518082805190602001908083835b602083106101a55780518252601f199092019160209182019101610186565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610205576040519150601f19603f3d011682016040523d82523d6000602084013e61020a565b606091505b505090508061021e573d806000803e806000fd5b505b505050565b600061022f610286565b905081600080516020610bcd83398151915255816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080516020610bcd8339815191525490565b610925806102a86000396000f3fe60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101745780638da5cb5b14610201578063f2fde38b1461023f576100ca565b806301ffc9a7146100d45780633659cfe614610134576100ca565b366100ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a4543544544000000000000000000000000000000000000604482015290519081900360640190fd5b6100d261027f565b005b3480156100e057600080fd5b50610120600480360360208110156100f757600080fd5b50357fffffffff00000000000000000000000000000000000000000000000000000000166102ca565b604080519115158252519081900360200190f35b34801561014057600080fd5b506100d26004803603602081101561015757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048d565b6100d26004803603604081101561018a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156101c257600080fd5b8201836020820111156101d457600080fd5b803590602001918460018302840111640100000000831117156101f657600080fd5b50909250905061054a565b34801561020d57600080fd5b50610216610630565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561024b57600080fd5b506100d26004803603602081101561026257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661063f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156102c0578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061035d57507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561036a57506001610488565b7fffffffff00000000000000000000000000000000000000000000000000000000808316141561039c57506000610488565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000085166004820152905173ffffffffffffffffffffffffffffffffffffffff8316916301ffc9a7916024808301926020929190829003018186803b15801561044c57600080fd5b505afa92505050801561047157506040513d602081101561046c57600080fd5b505160015b61047f576000915050610488565b91506104889050565b919050565b6104956106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b610547816040518060200160405280600081525061070e565b50565b6105526106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105eb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61062b8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061070e92505050565b505050565b600061063a6106e9565b905090565b6106476106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61054781610862565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511561062b5760008373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106107e957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107ac565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610849576040519150601f19603f3d011682016040523d82523d6000602084013e61084e565b606091505b50509050806102c4573d806000803e806000fd5b600061086c6106e9565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505056fea26469706673582212208c8442845e51519fe66269cee8fe054b83b7617dbcd8cf4d60740d273fa0b8a464736f6c63430007060033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", - "deployedBytecode": "0x60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101745780638da5cb5b14610201578063f2fde38b1461023f576100ca565b806301ffc9a7146100d45780633659cfe614610134576100ca565b366100ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a4543544544000000000000000000000000000000000000604482015290519081900360640190fd5b6100d261027f565b005b3480156100e057600080fd5b50610120600480360360208110156100f757600080fd5b50357fffffffff00000000000000000000000000000000000000000000000000000000166102ca565b604080519115158252519081900360200190f35b34801561014057600080fd5b506100d26004803603602081101561015757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048d565b6100d26004803603604081101561018a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156101c257600080fd5b8201836020820111156101d457600080fd5b803590602001918460018302840111640100000000831117156101f657600080fd5b50909250905061054a565b34801561020d57600080fd5b50610216610630565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561024b57600080fd5b506100d26004803603602081101561026257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661063f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156102c0578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061035d57507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561036a57506001610488565b7fffffffff00000000000000000000000000000000000000000000000000000000808316141561039c57506000610488565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000085166004820152905173ffffffffffffffffffffffffffffffffffffffff8316916301ffc9a7916024808301926020929190829003018186803b15801561044c57600080fd5b505afa92505050801561047157506040513d602081101561046c57600080fd5b505160015b61047f576000915050610488565b91506104889050565b919050565b6104956106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b610547816040518060200160405280600081525061070e565b50565b6105526106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105eb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61062b8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061070e92505050565b505050565b600061063a6106e9565b905090565b6106476106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61054781610862565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511561062b5760008373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106107e957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107ac565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610849576040519150601f19603f3d011682016040523d82523d6000602084013e61084e565b606091505b50509050806102c4573d806000803e806000fd5b600061086c6106e9565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505056fea26469706673582212208c8442845e51519fe66269cee8fe054b83b7617dbcd8cf4d60740d273fa0b8a464736f6c63430007060033", - "implementation": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "numDeployments": 2, + "solcInputHash": "41a8600e180880fe88609322a6b2ac21", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/proxy/EIP173Proxy.sol\":\"EIP173Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/proxy/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setOwner(ownerAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function owner() external view returns (address) {\\n return _owner();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferOwnership(address newOwner) external onlyOwner {\\n _setOwner(newOwner);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyOwner {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyOwner() {\\n require(msg.sender == _owner(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _owner() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\\n }\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address previousOwner = _owner();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\\n }\\n emit OwnershipTransferred(previousOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xb9c14a66c8a4eefabca13cc8dd8133c1587909bb1124fa793c50ab46358b63e4\",\"license\":\"MIT\"},\"solc_0.8/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data) internal {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\\n }\\n\\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x68c8cf1a340a53d31de8ed808bb66d64e83d50b20d80a0b2dff6aba903cebc98\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260405162000ccc38038062000ccc8339810160408190526200002691620001fc565b62000032838262000046565b6200003d8262000128565b505050620002fa565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8054908390556040516001600160a01b0380851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511562000123576000836001600160a01b031683604051620000ca9190620002dc565b600060405180830381855af49150503d806000811462000107576040519150601f19603f3d011682016040523d82523d6000602084013e6200010c565b606091505b505090508062000121573d806000803e806000fd5b505b505050565b60006200014260008051602062000cac8339815191525490565b90508160008051602062000cac83398151915255816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b80516001600160a01b0381168114620001b257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ea578181015183820152602001620001d0565b83811115620001215750506000910152565b6000806000606084860312156200021257600080fd5b6200021d846200019a565b92506200022d602085016200019a565b60408501519092506001600160401b03808211156200024b57600080fd5b818601915086601f8301126200026057600080fd5b815181811115620002755762000275620001b7565b604051601f8201601f19908116603f01168101908382118183101715620002a057620002a0620001b7565b81604052828152896020848701011115620002ba57600080fd5b620002cd836020830160208801620001cd565b80955050505050509250925092565b60008251620002f0818460208701620001cd565b9190910192915050565b6109a2806200030a6000396000f3fe60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101295780638da5cb5b1461013c578063f2fde38b14610176576100ca565b806301ffc9a7146100d45780633659cfe614610109576100ca565b366100ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a454354454400000000000000000000000000000000000060448201526064015b60405180910390fd5b6100d2610196565b005b3480156100e057600080fd5b506100f46100ef366004610806565b6101e1565b60405190151581526020015b60405180910390f35b34801561011557600080fd5b506100d2610124366004610871565b6103af565b6100d261013736600461088c565b610481565b34801561014857600080fd5b5061015161057c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b34801561018257600080fd5b506100d2610191366004610871565b6105ab565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156101d7578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061027457507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561028157506001919050565b7fffffffff0000000000000000000000000000000000000000000000000000000080831614156102b357506000919050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa92505050801561039b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526103989181019061090f565b60015b6103a85750600092915050565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e816040518060200160405280600081525061066a565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b6105778383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066a92505050565b505050565b60006105a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e81610759565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a38151156105775760008373ffffffffffffffffffffffffffffffffffffffff16836040516107059190610931565b600060405180830381855af49150503d8060008114610740576040519150601f19603f3d011682016040523d82523d6000602084013e610745565b606091505b50509050806101db573d806000803e806000fd5b60006107837fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020828403121561081857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146103a857600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461086c57600080fd5b919050565b60006020828403121561088357600080fd5b6103a882610848565b6000806000604084860312156108a157600080fd5b6108aa84610848565b9250602084013567ffffffffffffffff808211156108c757600080fd5b818601915086601f8301126108db57600080fd5b8135818111156108ea57600080fd5b8760208285010111156108fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561092157600080fd5b815180151581146103a857600080fd5b6000825160005b818110156109525760208186018101518583015201610938565b81811115610961576000828501525b50919091019291505056fea2646970667358221220d2ec357659da93a66b21590e3c56e508e51e4de5703da4d1f7ba0b98d9e047f964736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101295780638da5cb5b1461013c578063f2fde38b14610176576100ca565b806301ffc9a7146100d45780633659cfe614610109576100ca565b366100ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a454354454400000000000000000000000000000000000060448201526064015b60405180910390fd5b6100d2610196565b005b3480156100e057600080fd5b506100f46100ef366004610806565b6101e1565b60405190151581526020015b60405180910390f35b34801561011557600080fd5b506100d2610124366004610871565b6103af565b6100d261013736600461088c565b610481565b34801561014857600080fd5b5061015161057c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b34801561018257600080fd5b506100d2610191366004610871565b6105ab565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156101d7578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061027457507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561028157506001919050565b7fffffffff0000000000000000000000000000000000000000000000000000000080831614156102b357506000919050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa92505050801561039b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526103989181019061090f565b60015b6103a85750600092915050565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e816040518060200160405280600081525061066a565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b6105778383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066a92505050565b505050565b60006105a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e81610759565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a38151156105775760008373ffffffffffffffffffffffffffffffffffffffff16836040516107059190610931565b600060405180830381855af49150503d8060008114610740576040519150601f19603f3d011682016040523d82523d6000602084013e610745565b606091505b50509050806101db573d806000803e806000fd5b60006107837fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020828403121561081857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146103a857600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461086c57600080fd5b919050565b60006020828403121561088357600080fd5b6103a882610848565b6000806000604084860312156108a157600080fd5b6108aa84610848565b9250602084013567ffffffffffffffff808211156108c757600080fd5b818601915086601f8301126108db57600080fd5b8135818111156108ea57600080fd5b8760208285010111156108fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561092157600080fd5b815180151581146103a857600080fd5b6000825160005b818110156109525760208186018101518583015201610938565b81811115610961576000828501525b50919091019291505056fea2646970667358221220d2ec357659da93a66b21590e3c56e508e51e4de5703da4d1f7ba0b98d9e047f964736f6c634300080a0033", + "implementation": "0xc33c50AFdFA40DF2a1E7874D445f0AE4ea734648", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/gnosis/Ops_Implementation.json b/deployments/gnosis/Ops_Implementation.json index 3eb1c46a..4562cf7b 100644 --- a/deployments/gnosis/Ops_Implementation.json +++ b/deployments/gnosis/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "address": "0xc33c50AFdFA40DF2a1E7874D445f0AE4ea734648", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0xb115b0d75dc87b8aeb492b7e7cc4993f1b8dc263f28f9ad4b338b0f1b6aa6ddc", + "transactionHash": "0x048a307f0c48dd192f6d2ec8ea5f01cc02f728366f0c33f14f4a8a2c1a8595c6", "receipt": { "to": null, "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", - "contractAddress": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", - "transactionIndex": 2, - "gasUsed": "2650216", + "contractAddress": "0xc33c50AFdFA40DF2a1E7874D445f0AE4ea734648", + "transactionIndex": 8, + "gasUsed": "2673374", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe3895527a1de381d032a806a9ccf3ab6dbb30e64fbd1d3622da0e0335fc1b00d", - "transactionHash": "0xb115b0d75dc87b8aeb492b7e7cc4993f1b8dc263f28f9ad4b338b0f1b6aa6ddc", + "blockHash": "0x4f9d701fd59208943921f06c6e28a4d61523a3cf609c2ccda83c5354210760d8", + "transactionHash": "0x048a307f0c48dd192f6d2ec8ea5f01cc02f728366f0c33f14f4a8a2c1a8595c6", "logs": [], - "blockNumber": 21336951, - "cumulativeGasUsed": "3418361", + "blockNumber": 21595877, + "cumulativeGasUsed": "5988024", "status": 1, "byzantium": true }, "args": [ "0x29b6603D17B9D8f021EcB8845B6FD06E1Adf89DE", - "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D" + "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/gnosis/TaskTreasuryUpgradable.json b/deployments/gnosis/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..45ea534c --- /dev/null +++ b/deployments/gnosis/TaskTreasuryUpgradable.json @@ -0,0 +1,647 @@ +{ + "address": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "transactionIndex": 1, + "gasUsed": "782862", + "logsBloom": "0x00100000000020000000000000000040000000000000000000000000000000000200000000000000000400000000000040000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000020000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000400000000000080000000000000000000000000000000000000000000000010000000000000000000000000000020000000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0x9aa92e75f8793c629a6e4b38d6adb8e4076b04464923cf2307f02cf29f2ad2de", + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 21594902, + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "address": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000079f6022e7a8ff6d63a453e8f94a4ea5f17f60069" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x9aa92e75f8793c629a6e4b38d6adb8e4076b04464923cf2307f02cf29f2ad2de" + }, + { + "transactionIndex": 1, + "blockNumber": 21594902, + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "address": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x9aa92e75f8793c629a6e4b38d6adb8e4076b04464923cf2307f02cf29f2ad2de" + } + ], + "blockNumber": 21594902, + "cumulativeGasUsed": "975464", + "status": 1, + "byzantium": true + }, + "args": [ + "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000001bc16d674ec80000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x1bc16d674ec80000" + } + ] + }, + "implementation": "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/gnosis/TaskTreasuryUpgradable_Implementation.json b/deployments/gnosis/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..150115a2 --- /dev/null +++ b/deployments/gnosis/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,749 @@ +{ + "address": "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x60653b065249bedbb147a55725cdb7b9980a346d368a29d8c3946e6a710226f4", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "transactionIndex": 1, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x048573443f15eb503c2c36af0f7a0378cbd7a2b73992d36b8ab9c6006e9dd26b", + "transactionHash": "0x60653b065249bedbb147a55725cdb7b9980a346d368a29d8c3946e6a710226f4", + "logs": [], + "blockNumber": 21594900, + "cumulativeGasUsed": "3606723", + "status": 1, + "byzantium": true + }, + "args": ["0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D"], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/gnosis/TaskTreasuryUpgradable_Proxy.json b/deployments/gnosis/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..3c91cc1e --- /dev/null +++ b/deployments/gnosis/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,218 @@ +{ + "address": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "transactionIndex": 1, + "gasUsed": "782862", + "logsBloom": "0x00100000000020000000000000000040000000000000000000000000000000000200000000000000000400000000000040000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000020000000010000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000400000000000080000000000000000000000000000000000000000000000010000000000000000000000000000020000000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0x9aa92e75f8793c629a6e4b38d6adb8e4076b04464923cf2307f02cf29f2ad2de", + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 21594902, + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "address": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000079f6022e7a8ff6d63a453e8f94a4ea5f17f60069" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x9aa92e75f8793c629a6e4b38d6adb8e4076b04464923cf2307f02cf29f2ad2de" + }, + { + "transactionIndex": 1, + "blockNumber": 21594902, + "transactionHash": "0xb9ab6fd05a36d9359eacae99d9fc3c23e41a953f6fdc8503a6eaf1630c164785", + "address": "0x04462c8ad55a3d970fd9b4944A2f4C7c15700883", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x9aa92e75f8793c629a6e4b38d6adb8e4076b04464923cf2307f02cf29f2ad2de" + } + ], + "blockNumber": 21594902, + "cumulativeGasUsed": "975464", + "status": 1, + "byzantium": true + }, + "args": [ + "0x79f6022E7A8ff6D63A453E8f94a4Ea5F17f60069", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000001bc16d674ec80000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/gnosis/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/gnosis/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/gnosis/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/gnosis/solcInputs/41a8600e180880fe88609322a6b2ac21.json b/deployments/gnosis/solcInputs/41a8600e180880fe88609322a6b2ac21.json new file mode 100644 index 00000000..55724182 --- /dev/null +++ b/deployments/gnosis/solcInputs/41a8600e180880fe88609322a6b2ac21.json @@ -0,0 +1,39 @@ +{ + "language": "Solidity", + "sources": { + "solc_0.8/proxy/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setOwner(ownerAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function owner() external view returns (address) {\n return _owner();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n _setOwner(newOwner);\n }\n\n function upgradeTo(address newImplementation) external onlyOwner {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyOwner() {\n require(msg.sender == _owner(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _owner() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\n }\n }\n\n function _setOwner(address newOwner) internal {\n address previousOwner = _owner();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\n }\n emit OwnershipTransferred(previousOwner, newOwner);\n }\n}\n" + }, + "solc_0.8/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data) internal {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\n }\n\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "solc_0.8/proxy/EIP173ProxyWithReceive.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/goerli/Ops.json b/deployments/goerli/Ops.json index 5d79d64b..bda4e1c2 100644 --- a/deployments/goerli/Ops.json +++ b/deployments/goerli/Ops.json @@ -155,6 +155,12 @@ "internalType": "bytes32", "name": "taskId", "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "callSuccess", + "type": "bool" } ], "name": "ExecSuccess", @@ -427,6 +433,11 @@ "name": "_useTaskTreasuryFunds", "type": "bool" }, + { + "internalType": "bool", + "name": "_revertOnFailure", + "type": "bool" + }, { "internalType": "bytes32", "name": "_resolverHash", @@ -654,7 +665,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -775,7 +786,803 @@ "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.7/proxy/EIP173Proxy.sol\":\"EIP173Proxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.7/proxy/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setOwner(ownerAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function owner() external view returns (address) {\\n return _owner();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferOwnership(address newOwner) external onlyOwner {\\n _setOwner(newOwner);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyOwner {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyOwner() {\\n require(msg.sender == _owner(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _owner() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\\n }\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address previousOwner = _owner();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\\n }\\n emit OwnershipTransferred(previousOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7f9bbb686cd29ade05acf0cec1bfded16f0ad8d7e3fcb9cf35cc8b04efdda744\",\"license\":\"MIT\"},\"solc_0.7/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data) internal {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\\n }\\n\\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfa071ffed5c967384ac4787576322a46a4863d89bf39cd6fde58d4780b42e0ed\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x6080604052604051610bed380380610bed8339818101604052606081101561002657600080fd5b8151602083015160408085018051915193959294830192918464010000000082111561005157600080fd5b90830190602082018581111561006657600080fd5b825164010000000081118282018810171561008057600080fd5b82525081516020918201929091019080838360005b838110156100ad578181015183820152602001610095565b50505050905090810190601f1680156100da5780820380516001836020036101000a031916815260200191505b506040525050506100f1838261010260201b60201c565b6100fa82610225565b505050610299565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8054908390556040516001600160a01b0380851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a3815115610220576000836001600160a01b0316836040518082805190602001908083835b602083106101a55780518252601f199092019160209182019101610186565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610205576040519150601f19603f3d011682016040523d82523d6000602084013e61020a565b606091505b505090508061021e573d806000803e806000fd5b505b505050565b600061022f610286565b905081600080516020610bcd83398151915255816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080516020610bcd8339815191525490565b610925806102a86000396000f3fe60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101745780638da5cb5b14610201578063f2fde38b1461023f576100ca565b806301ffc9a7146100d45780633659cfe614610134576100ca565b366100ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a4543544544000000000000000000000000000000000000604482015290519081900360640190fd5b6100d261027f565b005b3480156100e057600080fd5b50610120600480360360208110156100f757600080fd5b50357fffffffff00000000000000000000000000000000000000000000000000000000166102ca565b604080519115158252519081900360200190f35b34801561014057600080fd5b506100d26004803603602081101561015757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048d565b6100d26004803603604081101561018a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156101c257600080fd5b8201836020820111156101d457600080fd5b803590602001918460018302840111640100000000831117156101f657600080fd5b50909250905061054a565b34801561020d57600080fd5b50610216610630565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561024b57600080fd5b506100d26004803603602081101561026257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661063f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156102c0578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061035d57507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561036a57506001610488565b7fffffffff00000000000000000000000000000000000000000000000000000000808316141561039c57506000610488565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000085166004820152905173ffffffffffffffffffffffffffffffffffffffff8316916301ffc9a7916024808301926020929190829003018186803b15801561044c57600080fd5b505afa92505050801561047157506040513d602081101561046c57600080fd5b505160015b61047f576000915050610488565b91506104889050565b919050565b6104956106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b610547816040518060200160405280600081525061070e565b50565b6105526106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105eb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61062b8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061070e92505050565b505050565b600061063a6106e9565b905090565b6106476106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61054781610862565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511561062b5760008373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106107e957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107ac565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610849576040519150601f19603f3d011682016040523d82523d6000602084013e61084e565b606091505b50509050806102c4573d806000803e806000fd5b600061086c6106e9565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505056fea26469706673582212208c8442845e51519fe66269cee8fe054b83b7617dbcd8cf4d60740d273fa0b8a464736f6c63430007060033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", "deployedBytecode": "0x60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101745780638da5cb5b14610201578063f2fde38b1461023f576100ca565b806301ffc9a7146100d45780633659cfe614610134576100ca565b366100ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a4543544544000000000000000000000000000000000000604482015290519081900360640190fd5b6100d261027f565b005b3480156100e057600080fd5b50610120600480360360208110156100f757600080fd5b50357fffffffff00000000000000000000000000000000000000000000000000000000166102ca565b604080519115158252519081900360200190f35b34801561014057600080fd5b506100d26004803603602081101561015757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048d565b6100d26004803603604081101561018a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156101c257600080fd5b8201836020820111156101d457600080fd5b803590602001918460018302840111640100000000831117156101f657600080fd5b50909250905061054a565b34801561020d57600080fd5b50610216610630565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561024b57600080fd5b506100d26004803603602081101561026257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661063f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156102c0578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061035d57507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561036a57506001610488565b7fffffffff00000000000000000000000000000000000000000000000000000000808316141561039c57506000610488565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000085166004820152905173ffffffffffffffffffffffffffffffffffffffff8316916301ffc9a7916024808301926020929190829003018186803b15801561044c57600080fd5b505afa92505050801561047157506040513d602081101561046c57600080fd5b505160015b61047f576000915050610488565b91506104889050565b919050565b6104956106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b610547816040518060200160405280600081525061070e565b50565b6105526106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105eb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61062b8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061070e92505050565b505050565b600061063a6106e9565b905090565b6106476106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61054781610862565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511561062b5760008373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106107e957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107ac565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610849576040519150601f19603f3d011682016040523d82523d6000602084013e61084e565b606091505b50509050806102c4573d806000803e806000fd5b600061086c6106e9565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505056fea26469706673582212208c8442845e51519fe66269cee8fe054b83b7617dbcd8cf4d60740d273fa0b8a464736f6c63430007060033", - "implementation": "0x756DF37020A2ace4c0472741789FaC469cfAD0a1", + "history": [ + { + "address": "0xc1C6805B857Bef1f412519C4A842522431aFed39", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "txFee", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "execAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "execData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + } + ], + "name": "ExecSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "taskCreator", + "type": "address" + } + ], + "name": "TaskCancelled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "taskCreator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "execAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "address", + "name": "resolverAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "resolverData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bool", + "name": "useTaskTreasuryFunds", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "resolverHash", + "type": "bytes32" + } + ], + "name": "TaskCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint128", + "name": "nextExec", + "type": "uint128" + }, + { + "indexed": true, + "internalType": "uint128", + "name": "interval", + "type": "uint128" + } + ], + "name": "TimerSet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_taskId", + "type": "bytes32" + } + ], + "name": "cancelTask", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + } + ], + "name": "createTask", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + } + ], + "name": "createTaskNoPrepayment", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_startTime", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "_interval", + "type": "uint128" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useTreasury", + "type": "bool" + } + ], + "name": "createTimedTask", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_txFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_taskCreator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useTaskTreasuryFunds", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "_resolverHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_execData", + "type": "bytes" + } + ], + "name": "exec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "execAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + } + ], + "name": "getResolverHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_func", + "type": "string" + } + ], + "name": "getSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_taskCreator", + "type": "address" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_useTaskTreasuryFunds", + "type": "bool" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_resolverHash", + "type": "bytes32" + } + ], + "name": "getTaskId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "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": "taskCreator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taskTreasury", + "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" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x64d8b5ffb3cc32714a63eb40def3e6c46c70ff9e8570c35e8d9d7fb4dbdfa728", + "receipt": { + "to": null, + "from": "0x8d26D02f7228F2527e226Cc6506B812A736a2CB2", + "contractAddress": "0xc1C6805B857Bef1f412519C4A842522431aFed39", + "transactionIndex": 1, + "gasUsed": "613532", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000408000040000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000020000000004800000000080000000010000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000200000000000000000000000000000000000000010000000000000000000000000000000000000000000020000000000000000000000400000000000000000000000000000000000000000000", + "blockHash": "0x298afd475fc981343e725595925d0480a90fa3825f99e696f727ad081d08ab24", + "transactionHash": "0x64d8b5ffb3cc32714a63eb40def3e6c46c70ff9e8570c35e8d9d7fb4dbdfa728", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 5537535, + "transactionHash": "0x64d8b5ffb3cc32714a63eb40def3e6c46c70ff9e8570c35e8d9d7fb4dbdfa728", + "address": "0xc1C6805B857Bef1f412519C4A842522431aFed39", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000756df37020a2ace4c0472741789fac469cfad0a1" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x298afd475fc981343e725595925d0480a90fa3825f99e696f727ad081d08ab24" + }, + { + "transactionIndex": 1, + "blockNumber": 5537535, + "transactionHash": "0x64d8b5ffb3cc32714a63eb40def3e6c46c70ff9e8570c35e8d9d7fb4dbdfa728", + "address": "0xc1C6805B857Bef1f412519C4A842522431aFed39", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008d26d02f7228f2527e226cc6506b812a736a2cb2" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x298afd475fc981343e725595925d0480a90fa3825f99e696f727ad081d08ab24" + } + ], + "blockNumber": 5537535, + "cumulativeGasUsed": "665022", + "status": 1, + "byzantium": true + }, + "args": [ + "0x756DF37020A2ace4c0472741789FaC469cfAD0a1", + "0x8d26D02f7228F2527e226Cc6506B812A736a2CB2", + "0x" + ], + "solcInputHash": "2db89642daf7ebd20cbbef9f4540b20d", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.7/proxy/EIP173Proxy.sol\":\"EIP173Proxy\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.7/proxy/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setOwner(ownerAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function owner() external view returns (address) {\\n return _owner();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferOwnership(address newOwner) external onlyOwner {\\n _setOwner(newOwner);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyOwner {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyOwner() {\\n require(msg.sender == _owner(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _owner() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\\n }\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address previousOwner = _owner();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\\n }\\n emit OwnershipTransferred(previousOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x7f9bbb686cd29ade05acf0cec1bfded16f0ad8d7e3fcb9cf35cc8b04efdda744\",\"license\":\"MIT\"},\"solc_0.7/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data) internal {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\\n }\\n\\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfa071ffed5c967384ac4787576322a46a4863d89bf39cd6fde58d4780b42e0ed\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052604051610bed380380610bed8339818101604052606081101561002657600080fd5b8151602083015160408085018051915193959294830192918464010000000082111561005157600080fd5b90830190602082018581111561006657600080fd5b825164010000000081118282018810171561008057600080fd5b82525081516020918201929091019080838360005b838110156100ad578181015183820152602001610095565b50505050905090810190601f1680156100da5780820380516001836020036101000a031916815260200191505b506040525050506100f1838261010260201b60201c565b6100fa82610225565b505050610299565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8054908390556040516001600160a01b0380851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a3815115610220576000836001600160a01b0316836040518082805190602001908083835b602083106101a55780518252601f199092019160209182019101610186565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610205576040519150601f19603f3d011682016040523d82523d6000602084013e61020a565b606091505b505090508061021e573d806000803e806000fd5b505b505050565b600061022f610286565b905081600080516020610bcd83398151915255816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080516020610bcd8339815191525490565b610925806102a86000396000f3fe60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101745780638da5cb5b14610201578063f2fde38b1461023f576100ca565b806301ffc9a7146100d45780633659cfe614610134576100ca565b366100ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a4543544544000000000000000000000000000000000000604482015290519081900360640190fd5b6100d261027f565b005b3480156100e057600080fd5b50610120600480360360208110156100f757600080fd5b50357fffffffff00000000000000000000000000000000000000000000000000000000166102ca565b604080519115158252519081900360200190f35b34801561014057600080fd5b506100d26004803603602081101561015757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048d565b6100d26004803603604081101561018a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156101c257600080fd5b8201836020820111156101d457600080fd5b803590602001918460018302840111640100000000831117156101f657600080fd5b50909250905061054a565b34801561020d57600080fd5b50610216610630565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561024b57600080fd5b506100d26004803603602081101561026257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661063f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156102c0578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061035d57507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561036a57506001610488565b7fffffffff00000000000000000000000000000000000000000000000000000000808316141561039c57506000610488565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000085166004820152905173ffffffffffffffffffffffffffffffffffffffff8316916301ffc9a7916024808301926020929190829003018186803b15801561044c57600080fd5b505afa92505050801561047157506040513d602081101561046c57600080fd5b505160015b61047f576000915050610488565b91506104889050565b919050565b6104956106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b610547816040518060200160405280600081525061070e565b50565b6105526106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105eb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61062b8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061070e92505050565b505050565b600061063a6106e9565b905090565b6106476106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61054781610862565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511561062b5760008373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106107e957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107ac565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610849576040519150601f19603f3d011682016040523d82523d6000602084013e61084e565b606091505b50509050806102c4573d806000803e806000fd5b600061086c6106e9565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505056fea26469706673582212208c8442845e51519fe66269cee8fe054b83b7617dbcd8cf4d60740d273fa0b8a464736f6c63430007060033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101745780638da5cb5b14610201578063f2fde38b1461023f576100ca565b806301ffc9a7146100d45780633659cfe614610134576100ca565b366100ca57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a4543544544000000000000000000000000000000000000604482015290519081900360640190fd5b6100d261027f565b005b3480156100e057600080fd5b50610120600480360360208110156100f757600080fd5b50357fffffffff00000000000000000000000000000000000000000000000000000000166102ca565b604080519115158252519081900360200190f35b34801561014057600080fd5b506100d26004803603602081101561015757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661048d565b6100d26004803603604081101561018a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691908101906040810160208201356401000000008111156101c257600080fd5b8201836020820111156101d457600080fd5b803590602001918460018302840111640100000000831117156101f657600080fd5b50909250905061054a565b34801561020d57600080fd5b50610216610630565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561024b57600080fd5b506100d26004803603602081101561026257600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661063f565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156102c0578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061035d57507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561036a57506001610488565b7fffffffff00000000000000000000000000000000000000000000000000000000808316141561039c57506000610488565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54604080517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000085166004820152905173ffffffffffffffffffffffffffffffffffffffff8316916301ffc9a7916024808301926020929190829003018186803b15801561044c57600080fd5b505afa92505050801561047157506040513d602081101561046c57600080fd5b505160015b61047f576000915050610488565b91506104889050565b919050565b6104956106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b610547816040518060200160405280600081525061070e565b50565b6105526106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105eb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61062b8383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061070e92505050565b505050565b600061063a6106e9565b905090565b6106476106e9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a4544000000000000000000000000000000000000604482015290519081900360640190fd5b61054781610862565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511561062b5760008373ffffffffffffffffffffffffffffffffffffffff16836040518082805190602001908083835b602083106107e957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107ac565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610849576040519150601f19603f3d011682016040523d82523d6000602084013e61084e565b606091505b50509050806102c4573d806000803e806000fd5b600061086c6106e9565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3505056fea26469706673582212208c8442845e51519fe66269cee8fe054b83b7617dbcd8cf4d60740d273fa0b8a464736f6c63430007060033", + "implementation": "0x756DF37020A2ace4c0472741789FaC469cfAD0a1", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } + } + ], + "implementation": "0x2d7d97B7D5D23bc735F0acCA324A6CEf93F25A85", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/goerli/Ops_Implementation.json b/deployments/goerli/Ops_Implementation.json index 3b7d0b4e..a15a72c7 100644 --- a/deployments/goerli/Ops_Implementation.json +++ b/deployments/goerli/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x756DF37020A2ace4c0472741789FaC469cfAD0a1", + "address": "0x2d7d97B7D5D23bc735F0acCA324A6CEf93F25A85", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -49,6 +49,12 @@ "internalType": "bytes32", "name": "taskId", "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "callSuccess", + "type": "bool" } ], "name": "ExecSuccess", @@ -321,6 +327,11 @@ "name": "_useTaskTreasuryFunds", "type": "bool" }, + { + "internalType": "bool", + "name": "_revertOnFailure", + "type": "bool" + }, { "internalType": "bytes32", "name": "_resolverHash", @@ -548,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -594,30 +605,30 @@ "type": "function" } ], - "transactionHash": "0xffa14741aa62c5cda07ebf127a6ad46846a50a3390b6c69f9b944ef92bd89e61", + "transactionHash": "0xcb735298b7dc7abad5c0933f0fd5f69506a76cca1ff1e1c2439e469ed81e3ca5", "receipt": { "to": null, "from": "0x8d26D02f7228F2527e226Cc6506B812A736a2CB2", - "contractAddress": "0x756DF37020A2ace4c0472741789FaC469cfAD0a1", + "contractAddress": "0x2d7d97B7D5D23bc735F0acCA324A6CEf93F25A85", "transactionIndex": 0, - "gasUsed": "2640117", + "gasUsed": "2673362", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7f968b27dea50dbc40041a630524fd3e3ede580ade32953705609d1dcb16ac27", - "transactionHash": "0xffa14741aa62c5cda07ebf127a6ad46846a50a3390b6c69f9b944ef92bd89e61", + "blockHash": "0xd4bdf489ef7b7dc1fa5cd0e7c6cbf1e4f5eaf2dcce728ce11d481eea8c683814", + "transactionHash": "0xcb735298b7dc7abad5c0933f0fd5f69506a76cca1ff1e1c2439e469ed81e3ca5", "logs": [], - "blockNumber": 5537533, - "cumulativeGasUsed": "2640117", + "blockNumber": 6692207, + "cumulativeGasUsed": "2673362", "status": 1, "byzantium": true }, "args": [ "0x683913B3A32ada4F8100458A3E1675425BdAa7DF", - "0xA0Cc0CC82d945D96D4F481A62C968AfCCea1C54F" + "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd" ], - "solcInputHash": "cc8f577406bc83ade29d7d1ff7ca1fb5", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/Gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/Gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x8d27abea158c1c23ce96b412b5fa13a9e14e9e825592c67fd13cb1eb1bef8bae\",\"license\":\"UNLICENSED\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./Gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./Gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./TaskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"3\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId\\n );\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) external returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) external {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(\\n taskCreator[task] == _taskCreator,\\n \\\"Ops: exec: No task found\\\"\\n );\\n\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n if (!success && !isTimedTask)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(_txFee, _feeToken, _execAddress, _execData, task);\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n}\\n\",\"keccak256\":\"0xb5fd10a4956ec7e34bba957bf76936768faea914db87f4277ad0b10227144cab\",\"license\":\"UNLICENSED\"},\"contracts/TaskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../Gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0xff6f244856efd3fd3f76bd8176d7adc3b1c2c9ace8d0129762cb45cd5e04e5d8\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030b7380380620030b78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612ee3620001d460003960008181610d5701526113790152600081816105d601526109040152612ee36000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638e8b5279116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638e8b527914610295578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063647846a5116100e9578063647846a5146101b75780636d2dd29f146101d55780637b4e45e91461020557806380a003ff146102355780638b92696a1461026557610116565b80630407145c1461011b5780632e6e0bd01461014b57806354fd4d501461017b578063573ea57514610199575b600080fd5b61013560048036038101906101309190611e41565b6103e9565b60405161014291906128b9565b60405180910390f35b61016560048036038101906101609190612059565b610568565b6040516101729190612725565b60405180910390f35b61018361059b565b604051610190919061296c565b60405180910390f35b6101a16105d4565b6040516101ae9190612740565b60405180910390f35b6101bf6105f8565b6040516101cc9190612725565b60405180910390f35b6101ef60048036038101906101ea9190612059565b61061e565b6040516101fc9190612725565b60405180910390f35b61021f600480360381019061021a9190611e6a565b610651565b60405161022c91906128db565b60405180910390f35b61024f600480360381019061024a9190612082565b610690565b60405161025c919061291f565b60405180910390f35b61027f600480360381019061027a9190611ef3565b6106b2565b60405161028c91906128db565b60405180910390f35b6102af60048036038101906102aa9190612195565b610902565b005b6102cb60048036038101906102c691906120c7565b610e8e565b6040516102d891906128db565b60405180910390f35b6102e9611062565b6040516102f7929190612a92565b60405180910390f35b61031a60048036038101906103159190612059565b611093565b604051610328929190612a4e565b60405180910390f35b61034b60048036038101906103469190611f73565b6110ef565b60405161035891906128db565b60405180910390f35b61037b60048036038101906103769190612005565b61133e565b60405161038891906128db565b60405180910390f35b610399611371565b6040516103a69190612a77565b60405180910390f35b6103b7611377565b6040516103c49190612725565b60405180910390f35b6103e760048036038101906103e29190612059565b61139b565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061167b565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061169090919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d0b565b9150506104ac565b508092505050919050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f330000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600086868686868660405160200161066e969594939291906127f1565b6040516020818303038152906040528051906020012090509695505050505050565b600082826040516106a29291906126a4565b6040518091039020905092915050565b6000806107038585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061133e565b90506107153388886001600086610651565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90612a0e565b60405180910390fd5b61080982600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206116a790919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a6040516108f09a9998979695949392919061275b565b60405180910390a15095945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109879061298e565b60405180910390fd5b846109de578760038190555086600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6000610a0487856109ef86866116be565b898a6109fb578c6109fe565b60005b8a610651565b90508673ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610aa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9d906129ae565b60405180910390fd5b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415610b00576000610b03565b60015b90508015610c8457426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161115610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b89906129ee565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff16610be09190612ba3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610610c46578360000160109054906101000a90046fffffffffffffffffffffffffffffffff1682610c3f9190612ba3565b9150610be8565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b6000808773ffffffffffffffffffffffffffffffffffffffff168787604051610cae9291906126a4565b6000604051808303816000865af19150503d8060008114610ceb576040519150601f19603f3d011682016040523d82523d6000602084013e610cf0565b606091505b509150915081158015610d01575082155b15610d4f57610d4e6040518060400160405280600c81526020017f506f6b654d652e657865633a0000000000000000000000000000000000000000815250826118cc90919063ffffffff16565b5b8915610de9577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8d8f8e6040518463ffffffff1660e01b8152600401610db293929190612882565b600060405180830381600087803b158015610dcc57600080fd5b505af1158015610de0573d6000803e3d6000fd5b50505050610e15565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8773ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff168e7ff5785831cc21ed1a6e74f60bd9268a70a7a3f3fc03c815dba22ceda33aea26ce8a8a8a604051610e779392919061293a565b60405180910390a450505050505050505050505050565b600080896fffffffffffffffffffffffffffffffff1611610ee4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edb90612a2e565b60405180910390fd5b8115610efe57610ef788888888886106b2565b9050610f0f565b610f0c8888888888886110ef565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610f305742610f32565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b6000806111408686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061133e565b905061115133898960008786610651565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146111f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111eb90612a0e565b60405180910390fd5b61124582600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206116a790919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161132b9a9998979695949392919061275b565b60405180910390a1509695505050505050565b60008282604051602001611353929190612852565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461143b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611432906129ce565b60405180910390fd5b61148c81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a3590919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156115d55760006115d8565b60015b9050801561163d5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161166e9291906128f6565b60405180910390a1505050565b600061168982600001611a4c565b9050919050565b600061169f8360000183611a5d565b905092915050565b60006116b68360000183611aae565b905092915050565b60006018838360038181106116fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611785577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60088585600181811061180e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c85856000818110611895577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b6004602083516118dc9190612d54565b14156119d9576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561197d5760448301925081836040516020016119329291906126bd565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611974919061296c565b60405180910390fd5b8160405160200161198e91906126e1565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d0919061296c565b60405180910390fd5b806040516020016119ea9190612703565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2c919061296c565b60405180910390fd5b6000611a448360000183611b1e565b905092915050565b600081600001805490509050919050565b6000826000018281548110611a9b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611aba8383611ca4565b611b13578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b18565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611c98576000600182611b509190612be9565b9050600060018660000180549050611b689190612be9565b9050818114611c23576000866000018281548110611baf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611bf9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c5d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611c9e565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611cda611cd584612aec565b612abb565b905082815260208101848484011115611cf257600080fd5b611cfd848285612cc9565b509392505050565b600081359050611d1481612e23565b92915050565b600081359050611d2981612e3a565b92915050565b600081359050611d3e81612e51565b92915050565b600081359050611d5381612e68565b92915050565b60008083601f840112611d6b57600080fd5b8235905067ffffffffffffffff811115611d8457600080fd5b602083019150836001820283011115611d9c57600080fd5b9250929050565b600082601f830112611db457600080fd5b8135611dc4848260208601611cc7565b91505092915050565b60008083601f840112611ddf57600080fd5b8235905067ffffffffffffffff811115611df857600080fd5b602083019150836001820283011115611e1057600080fd5b9250929050565b600081359050611e2681612e7f565b92915050565b600081359050611e3b81612e96565b92915050565b600060208284031215611e5357600080fd5b6000611e6184828501611d05565b91505092915050565b60008060008060008060c08789031215611e8357600080fd5b6000611e9189828a01611d05565b9650506020611ea289828a01611d05565b9550506040611eb389828a01611d44565b9450506060611ec489828a01611d1a565b9350506080611ed589828a01611d05565b92505060a0611ee689828a01611d2f565b9150509295509295509295565b600080600080600060808688031215611f0b57600080fd5b6000611f1988828901611d05565b9550506020611f2a88828901611d44565b9450506040611f3b88828901611d05565b935050606086013567ffffffffffffffff811115611f5857600080fd5b611f6488828901611d59565b92509250509295509295909350565b60008060008060008060a08789031215611f8c57600080fd5b6000611f9a89828a01611d05565b9650506020611fab89828a01611d44565b9550506040611fbc89828a01611d05565b945050606087013567ffffffffffffffff811115611fd957600080fd5b611fe589828a01611d59565b93509350506080611ff889828a01611d05565b9150509295509295509295565b6000806040838503121561201857600080fd5b600061202685828601611d05565b925050602083013567ffffffffffffffff81111561204357600080fd5b61204f85828601611da3565b9150509250929050565b60006020828403121561206b57600080fd5b600061207984828501611d2f565b91505092915050565b6000806020838503121561209557600080fd5b600083013567ffffffffffffffff8111156120af57600080fd5b6120bb85828601611dcd565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120e657600080fd5b60006120f48c828d01611e17565b99505060206121058c828d01611e17565b98505060406121168c828d01611d05565b97505060606121278c828d01611d44565b96505060806121388c828d01611d05565b95505060a08a013567ffffffffffffffff81111561215557600080fd5b6121618c828d01611d59565b945094505060c06121748c828d01611d05565b92505060e06121858c828d01611d1a565b9150509295985092959850929598565b60008060008060008060008060e0898b0312156121b157600080fd5b60006121bf8b828c01611e2c565b98505060206121d08b828c01611d05565b97505060406121e18b828c01611d05565b96505060606121f28b828c01611d1a565b95505060806122038b828c01611d2f565b94505060a06122148b828c01611d05565b93505060c089013567ffffffffffffffff81111561223157600080fd5b61223d8b828c01611d59565b92509250509295985092959890939650565b600061225b83836122f2565b60208301905092915050565b61227081612c2f565b82525050565b61227f81612c1d565b82525050565b600061229082612b2c565b61229a8185612b5a565b93506122a583612b1c565b8060005b838110156122d65781516122bd888261224f565b97506122c883612b4d565b9250506001810190506122a9565b5085935050505092915050565b6122ec81612c41565b82525050565b6122fb81612c4d565b82525050565b61230a81612c4d565b82525050565b61231981612c57565b82525050565b600061232b8385612b6b565b9350612338838584612cc9565b61234183612e12565b840190509392505050565b60006123588385612b7c565b9350612365838584612cc9565b82840190509392505050565b600061237c82612b37565b6123868185612b6b565b9350612396818560208601612cd8565b61239f81612e12565b840191505092915050565b60006123b582612b42565b6123bf8185612b87565b93506123cf818560208601612cd8565b6123d881612e12565b840191505092915050565b60006123ee82612b42565b6123f88185612b98565b9350612408818560208601612cd8565b80840191505092915050565b6000612421601783612b87565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612461601b83612b87565b91507f506f6b654d653a20657865633a204e6f207461736b20666f756e6400000000006000830152602082019050919050565b60006124a1600f83612b98565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006124e1603183612b87565b91507f506f6b654d653a2063616e63656c5461736b3a2053656e64657220646964206e60008301527f6f74207374617274207461736b207965740000000000000000000000000000006020830152604082019050919050565b6000612547601783612b87565b91507f506f6b654d653a20657865633a20546f6f206561726c790000000000000000006000830152602082019050919050565b6000612587602f83612b87565b91507f506f6b654d653a206372656174655461736b3a2053656e64657220616c72656160008301527f64792073746172746564207461736b00000000000000000000000000000000006020830152604082019050919050565b60006125ed602d83612b87565b91507f506f6b654d653a2063726561746554696d65645461736b3a20696e746572766160008301527f6c2063616e6e6f742062652030000000000000000000000000000000000000006020830152604082019050919050565b6000612653601483612b98565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b61268f81612c83565b82525050565b61269e81612cbf565b82525050565b60006126b182848661234c565b91508190509392505050565b60006126c982856123e3565b91506126d582846123e3565b91508190509392505050565b60006126ed82846123e3565b91506126f882612494565b915081905092915050565b600061270f82846123e3565b915061271a82612646565b915081905092915050565b600060208201905061273a6000830184612276565b92915050565b60006020820190506127556000830184612267565b92915050565b600061012082019050612771600083018d612276565b61277e602083018c612276565b61278b604083018b612310565b612798606083018a612276565b6127a56080830189612301565b81810360a08301526127b881878961231f565b90506127c760c08301866122e3565b6127d460e0830185612276565b6127e2610100830184612301565b9b9a5050505050505050505050565b600060c0820190506128066000830189612276565b6128136020830188612276565b6128206040830187612310565b61282d60608301866122e3565b61283a6080830185612276565b61284760a0830184612301565b979650505050505050565b60006040820190506128676000830185612276565b81810360208301526128798184612371565b90509392505050565b60006060820190506128976000830186612276565b6128a46020830185612695565b6128b16040830184612276565b949350505050565b600060208201905081810360008301526128d38184612285565b905092915050565b60006020820190506128f06000830184612301565b92915050565b600060408201905061290b6000830185612301565b6129186020830184612276565b9392505050565b60006020820190506129346000830184612310565b92915050565b6000604082019050818103600083015261295581858761231f565b90506129646020830184612301565b949350505050565b6000602082019050818103600083015261298681846123aa565b905092915050565b600060208201905081810360008301526129a781612414565b9050919050565b600060208201905081810360008301526129c781612454565b9050919050565b600060208201905081810360008301526129e7816124d4565b9050919050565b60006020820190508181036000830152612a078161253a565b9050919050565b60006020820190508181036000830152612a278161257a565b9050919050565b60006020820190508181036000830152612a47816125e0565b9050919050565b6000604082019050612a636000830185612686565b612a706020830184612686565b9392505050565b6000602082019050612a8c6000830184612695565b92915050565b6000604082019050612aa76000830185612695565b612ab46020830184612276565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612ae257612ae1612de3565b5b8060405250919050565b600067ffffffffffffffff821115612b0757612b06612de3565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bae82612c83565b9150612bb983612c83565b9250826fffffffffffffffffffffffffffffffff03821115612bde57612bdd612d85565b5b828201905092915050565b6000612bf482612cbf565b9150612bff83612cbf565b925082821015612c1257612c11612d85565b5b828203905092915050565b6000612c2882612c9f565b9050919050565b6000612c3a82612c9f565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612cf6578082015181840152602081019050612cdb565b83811115612d05576000848401525b50505050565b6000612d1682612cbf565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d4957612d48612d85565b5b600182019050919050565b6000612d5f82612cbf565b9150612d6a83612cbf565b925082612d7a57612d79612db4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e2c81612c1d565b8114612e3757600080fd5b50565b612e4381612c41565b8114612e4e57600080fd5b50565b612e5a81612c4d565b8114612e6557600080fd5b50565b612e7181612c57565b8114612e7c57600080fd5b50565b612e8881612c83565b8114612e9357600080fd5b50565b612e9f81612cbf565b8114612eaa57600080fd5b5056fea2646970667358221220eab72c3f967534716767eff989fb48fa7223e3cdb90f12ff011ed2732306f64f64736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638e8b5279116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638e8b527914610295578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063647846a5116100e9578063647846a5146101b75780636d2dd29f146101d55780637b4e45e91461020557806380a003ff146102355780638b92696a1461026557610116565b80630407145c1461011b5780632e6e0bd01461014b57806354fd4d501461017b578063573ea57514610199575b600080fd5b61013560048036038101906101309190611e41565b6103e9565b60405161014291906128b9565b60405180910390f35b61016560048036038101906101609190612059565b610568565b6040516101729190612725565b60405180910390f35b61018361059b565b604051610190919061296c565b60405180910390f35b6101a16105d4565b6040516101ae9190612740565b60405180910390f35b6101bf6105f8565b6040516101cc9190612725565b60405180910390f35b6101ef60048036038101906101ea9190612059565b61061e565b6040516101fc9190612725565b60405180910390f35b61021f600480360381019061021a9190611e6a565b610651565b60405161022c91906128db565b60405180910390f35b61024f600480360381019061024a9190612082565b610690565b60405161025c919061291f565b60405180910390f35b61027f600480360381019061027a9190611ef3565b6106b2565b60405161028c91906128db565b60405180910390f35b6102af60048036038101906102aa9190612195565b610902565b005b6102cb60048036038101906102c691906120c7565b610e8e565b6040516102d891906128db565b60405180910390f35b6102e9611062565b6040516102f7929190612a92565b60405180910390f35b61031a60048036038101906103159190612059565b611093565b604051610328929190612a4e565b60405180910390f35b61034b60048036038101906103469190611f73565b6110ef565b60405161035891906128db565b60405180910390f35b61037b60048036038101906103769190612005565b61133e565b60405161038891906128db565b60405180910390f35b610399611371565b6040516103a69190612a77565b60405180910390f35b6103b7611377565b6040516103c49190612725565b60405180910390f35b6103e760048036038101906103e29190612059565b61139b565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061167b565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061169090919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d0b565b9150506104ac565b508092505050919050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f330000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600086868686868660405160200161066e969594939291906127f1565b6040516020818303038152906040528051906020012090509695505050505050565b600082826040516106a29291906126a4565b6040518091039020905092915050565b6000806107038585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061133e565b90506107153388886001600086610651565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107af90612a0e565b60405180910390fd5b61080982600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206116a790919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a6040516108f09a9998979695949392919061275b565b60405180910390a15095945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610990576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109879061298e565b60405180910390fd5b846109de578760038190555086600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6000610a0487856109ef86866116be565b898a6109fb578c6109fe565b60005b8a610651565b90508673ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610aa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9d906129ae565b60405180910390fd5b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415610b00576000610b03565b60015b90508015610c8457426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161115610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b89906129ee565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff16610be09190612ba3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610610c46578360000160109054906101000a90046fffffffffffffffffffffffffffffffff1682610c3f9190612ba3565b9150610be8565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b6000808773ffffffffffffffffffffffffffffffffffffffff168787604051610cae9291906126a4565b6000604051808303816000865af19150503d8060008114610ceb576040519150601f19603f3d011682016040523d82523d6000602084013e610cf0565b606091505b509150915081158015610d01575082155b15610d4f57610d4e6040518060400160405280600c81526020017f506f6b654d652e657865633a0000000000000000000000000000000000000000815250826118cc90919063ffffffff16565b5b8915610de9577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8d8f8e6040518463ffffffff1660e01b8152600401610db293929190612882565b600060405180830381600087803b158015610dcc57600080fd5b505af1158015610de0573d6000803e3d6000fd5b50505050610e15565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8773ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff168e7ff5785831cc21ed1a6e74f60bd9268a70a7a3f3fc03c815dba22ceda33aea26ce8a8a8a604051610e779392919061293a565b60405180910390a450505050505050505050505050565b600080896fffffffffffffffffffffffffffffffff1611610ee4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edb90612a2e565b60405180910390fd5b8115610efe57610ef788888888886106b2565b9050610f0f565b610f0c8888888888886110ef565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610f305742610f32565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b6000806111408686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061133e565b905061115133898960008786610651565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146111f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111eb90612a0e565b60405180910390fd5b61124582600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206116a790919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161132b9a9998979695949392919061275b565b60405180910390a1509695505050505050565b60008282604051602001611353929190612852565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461143b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611432906129ce565b60405180910390fd5b61148c81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a3590919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156115d55760006115d8565b60015b9050801561163d5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161166e9291906128f6565b60405180910390a1505050565b600061168982600001611a4c565b9050919050565b600061169f8360000183611a5d565b905092915050565b60006116b68360000183611aae565b905092915050565b60006018838360038181106116fc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611785577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60088585600181811061180e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c85856000818110611895577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b6004602083516118dc9190612d54565b14156119d9576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561197d5760448301925081836040516020016119329291906126bd565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611974919061296c565b60405180910390fd5b8160405160200161198e91906126e1565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119d0919061296c565b60405180910390fd5b806040516020016119ea9190612703565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2c919061296c565b60405180910390fd5b6000611a448360000183611b1e565b905092915050565b600081600001805490509050919050565b6000826000018281548110611a9b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611aba8383611ca4565b611b13578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b18565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611c98576000600182611b509190612be9565b9050600060018660000180549050611b689190612be9565b9050818114611c23576000866000018281548110611baf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611bf9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c5d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611c9e565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611cda611cd584612aec565b612abb565b905082815260208101848484011115611cf257600080fd5b611cfd848285612cc9565b509392505050565b600081359050611d1481612e23565b92915050565b600081359050611d2981612e3a565b92915050565b600081359050611d3e81612e51565b92915050565b600081359050611d5381612e68565b92915050565b60008083601f840112611d6b57600080fd5b8235905067ffffffffffffffff811115611d8457600080fd5b602083019150836001820283011115611d9c57600080fd5b9250929050565b600082601f830112611db457600080fd5b8135611dc4848260208601611cc7565b91505092915050565b60008083601f840112611ddf57600080fd5b8235905067ffffffffffffffff811115611df857600080fd5b602083019150836001820283011115611e1057600080fd5b9250929050565b600081359050611e2681612e7f565b92915050565b600081359050611e3b81612e96565b92915050565b600060208284031215611e5357600080fd5b6000611e6184828501611d05565b91505092915050565b60008060008060008060c08789031215611e8357600080fd5b6000611e9189828a01611d05565b9650506020611ea289828a01611d05565b9550506040611eb389828a01611d44565b9450506060611ec489828a01611d1a565b9350506080611ed589828a01611d05565b92505060a0611ee689828a01611d2f565b9150509295509295509295565b600080600080600060808688031215611f0b57600080fd5b6000611f1988828901611d05565b9550506020611f2a88828901611d44565b9450506040611f3b88828901611d05565b935050606086013567ffffffffffffffff811115611f5857600080fd5b611f6488828901611d59565b92509250509295509295909350565b60008060008060008060a08789031215611f8c57600080fd5b6000611f9a89828a01611d05565b9650506020611fab89828a01611d44565b9550506040611fbc89828a01611d05565b945050606087013567ffffffffffffffff811115611fd957600080fd5b611fe589828a01611d59565b93509350506080611ff889828a01611d05565b9150509295509295509295565b6000806040838503121561201857600080fd5b600061202685828601611d05565b925050602083013567ffffffffffffffff81111561204357600080fd5b61204f85828601611da3565b9150509250929050565b60006020828403121561206b57600080fd5b600061207984828501611d2f565b91505092915050565b6000806020838503121561209557600080fd5b600083013567ffffffffffffffff8111156120af57600080fd5b6120bb85828601611dcd565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120e657600080fd5b60006120f48c828d01611e17565b99505060206121058c828d01611e17565b98505060406121168c828d01611d05565b97505060606121278c828d01611d44565b96505060806121388c828d01611d05565b95505060a08a013567ffffffffffffffff81111561215557600080fd5b6121618c828d01611d59565b945094505060c06121748c828d01611d05565b92505060e06121858c828d01611d1a565b9150509295985092959850929598565b60008060008060008060008060e0898b0312156121b157600080fd5b60006121bf8b828c01611e2c565b98505060206121d08b828c01611d05565b97505060406121e18b828c01611d05565b96505060606121f28b828c01611d1a565b95505060806122038b828c01611d2f565b94505060a06122148b828c01611d05565b93505060c089013567ffffffffffffffff81111561223157600080fd5b61223d8b828c01611d59565b92509250509295985092959890939650565b600061225b83836122f2565b60208301905092915050565b61227081612c2f565b82525050565b61227f81612c1d565b82525050565b600061229082612b2c565b61229a8185612b5a565b93506122a583612b1c565b8060005b838110156122d65781516122bd888261224f565b97506122c883612b4d565b9250506001810190506122a9565b5085935050505092915050565b6122ec81612c41565b82525050565b6122fb81612c4d565b82525050565b61230a81612c4d565b82525050565b61231981612c57565b82525050565b600061232b8385612b6b565b9350612338838584612cc9565b61234183612e12565b840190509392505050565b60006123588385612b7c565b9350612365838584612cc9565b82840190509392505050565b600061237c82612b37565b6123868185612b6b565b9350612396818560208601612cd8565b61239f81612e12565b840191505092915050565b60006123b582612b42565b6123bf8185612b87565b93506123cf818560208601612cd8565b6123d881612e12565b840191505092915050565b60006123ee82612b42565b6123f88185612b98565b9350612408818560208601612cd8565b80840191505092915050565b6000612421601783612b87565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612461601b83612b87565b91507f506f6b654d653a20657865633a204e6f207461736b20666f756e6400000000006000830152602082019050919050565b60006124a1600f83612b98565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006124e1603183612b87565b91507f506f6b654d653a2063616e63656c5461736b3a2053656e64657220646964206e60008301527f6f74207374617274207461736b207965740000000000000000000000000000006020830152604082019050919050565b6000612547601783612b87565b91507f506f6b654d653a20657865633a20546f6f206561726c790000000000000000006000830152602082019050919050565b6000612587602f83612b87565b91507f506f6b654d653a206372656174655461736b3a2053656e64657220616c72656160008301527f64792073746172746564207461736b00000000000000000000000000000000006020830152604082019050919050565b60006125ed602d83612b87565b91507f506f6b654d653a2063726561746554696d65645461736b3a20696e746572766160008301527f6c2063616e6e6f742062652030000000000000000000000000000000000000006020830152604082019050919050565b6000612653601483612b98565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b61268f81612c83565b82525050565b61269e81612cbf565b82525050565b60006126b182848661234c565b91508190509392505050565b60006126c982856123e3565b91506126d582846123e3565b91508190509392505050565b60006126ed82846123e3565b91506126f882612494565b915081905092915050565b600061270f82846123e3565b915061271a82612646565b915081905092915050565b600060208201905061273a6000830184612276565b92915050565b60006020820190506127556000830184612267565b92915050565b600061012082019050612771600083018d612276565b61277e602083018c612276565b61278b604083018b612310565b612798606083018a612276565b6127a56080830189612301565b81810360a08301526127b881878961231f565b90506127c760c08301866122e3565b6127d460e0830185612276565b6127e2610100830184612301565b9b9a5050505050505050505050565b600060c0820190506128066000830189612276565b6128136020830188612276565b6128206040830187612310565b61282d60608301866122e3565b61283a6080830185612276565b61284760a0830184612301565b979650505050505050565b60006040820190506128676000830185612276565b81810360208301526128798184612371565b90509392505050565b60006060820190506128976000830186612276565b6128a46020830185612695565b6128b16040830184612276565b949350505050565b600060208201905081810360008301526128d38184612285565b905092915050565b60006020820190506128f06000830184612301565b92915050565b600060408201905061290b6000830185612301565b6129186020830184612276565b9392505050565b60006020820190506129346000830184612310565b92915050565b6000604082019050818103600083015261295581858761231f565b90506129646020830184612301565b949350505050565b6000602082019050818103600083015261298681846123aa565b905092915050565b600060208201905081810360008301526129a781612414565b9050919050565b600060208201905081810360008301526129c781612454565b9050919050565b600060208201905081810360008301526129e7816124d4565b9050919050565b60006020820190508181036000830152612a078161253a565b9050919050565b60006020820190508181036000830152612a278161257a565b9050919050565b60006020820190508181036000830152612a47816125e0565b9050919050565b6000604082019050612a636000830185612686565b612a706020830184612686565b9392505050565b6000602082019050612a8c6000830184612695565b92915050565b6000604082019050612aa76000830185612695565b612ab46020830184612276565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612ae257612ae1612de3565b5b8060405250919050565b600067ffffffffffffffff821115612b0757612b06612de3565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bae82612c83565b9150612bb983612c83565b9250826fffffffffffffffffffffffffffffffff03821115612bde57612bdd612d85565b5b828201905092915050565b6000612bf482612cbf565b9150612bff83612cbf565b925082821015612c1257612c11612d85565b5b828203905092915050565b6000612c2882612c9f565b9050919050565b6000612c3a82612c9f565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612cf6578082015181840152602081019050612cdb565b83811115612d05576000848401525b50505050565b6000612d1682612cbf565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d4957612d48612d85565b5b600182019050919050565b6000612d5f82612cbf565b9150612d6a83612cbf565b925082612d7a57612d79612db4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e2c81612c1d565b8114612e3757600080fd5b50565b612e4381612c41565b8114612e4e57600080fd5b50565b612e5a81612c4d565b8114612e6557600080fd5b50565b612e7181612c57565b8114612e7c57600080fd5b50565b612e8881612c83565b8114612e9357600080fd5b50565b612e9f81612cbf565b8114612eaa57600080fd5b5056fea2646970667358221220eab72c3f967534716767eff989fb48fa7223e3cdb90f12ff011ed2732306f64f64736f6c63430008000033", + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -657,11 +668,12 @@ "_useTreasury": "True if Gelato should charge fees from TaskTreasury, false if not" } }, - "exec(uint256,address,address,bool,bytes32,address,bytes)": { + "exec(uint256,address,address,bool,bool,bytes32,address,bytes)": { "params": { "_execAddress": "On which contract should Gelato execute the tx", "_execData": "Data used to execute the tx, queried from the Resolver by Gelato", "_feeToken": "Token used to pay for the execution. ETH = 0xeeeeee...", + "_revertOnFailure": "To revert or not if call to execAddress fails", "_taskCreator": "On which contract should Gelato check when to execute the tx", "_txFee": "Fee paid to Gelato for execution, deducted on the TaskTreasury", "_useTaskTreasuryFunds": "If msg.sender's balance on TaskTreasury should pay for the tx" @@ -712,7 +724,7 @@ "createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)": { "notice": "Create a timed task that executes every so often based on the inputted interval" }, - "exec(uint256,address,address,bool,bytes32,address,bytes)": { + "exec(uint256,address,address,bool,bool,bytes32,address,bytes)": { "notice": "Execution API called by Gelato" }, "getFeeDetails()": { @@ -737,7 +749,7 @@ "storageLayout": { "storage": [ { - "astId": 2170, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -745,7 +757,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 2174, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -753,15 +765,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 2179, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 2183, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -769,7 +781,7 @@ "type": "t_uint256" }, { - "astId": 2185, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -777,12 +789,12 @@ "type": "t_address" }, { - "astId": 2190, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)2163_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -802,12 +814,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -816,12 +828,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)2163_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)2163_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -830,27 +842,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -858,7 +870,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -868,12 +880,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)2163_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 2160, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -881,7 +893,7 @@ "type": "t_uint128" }, { - "astId": 2162, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/goerli/TaskTreasuryUpgradable.json b/deployments/goerli/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..5a3bc39f --- /dev/null +++ b/deployments/goerli/TaskTreasuryUpgradable.json @@ -0,0 +1,646 @@ +{ + "address": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "transactionIndex": 2, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000800000000000000000000000000020000000000810000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000000000010000000000000000000000000000020000000000000000000000400000000000002000000000000010000100000000000", + "blockHash": "0x6f3f809eea5f9bf9c72a445cf94c20752e497d7403dae2c730f106b7f0ee278e", + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 6672542, + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "address": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000003f2b8c176a61845327f442a91160c14254dc2a91" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x6f3f809eea5f9bf9c72a445cf94c20752e497d7403dae2c730f106b7f0ee278e" + }, + { + "transactionIndex": 2, + "blockNumber": 6672542, + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "address": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x6f3f809eea5f9bf9c72a445cf94c20752e497d7403dae2c730f106b7f0ee278e" + } + ], + "blockNumber": 6672542, + "cumulativeGasUsed": "855814", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3F2b8C176a61845327f442a91160C14254dc2A91", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x00" + } + ] + }, + "implementation": "0x3F2b8C176a61845327f442a91160C14254dc2A91", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/goerli/TaskTreasuryUpgradable_Implementation.json b/deployments/goerli/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..24222a6c --- /dev/null +++ b/deployments/goerli/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,748 @@ +{ + "address": "0x3F2b8C176a61845327f442a91160C14254dc2A91", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xbcdde466827642ebd795a5ba66077cfefd099d24daab4902e4d8a592d1cf5008", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x3F2b8C176a61845327f442a91160C14254dc2A91", + "transactionIndex": 5, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x40f0d7ed5a7e981b1daa22963028909ccf711ee85d6775189fbf31d4c65fef58", + "transactionHash": "0xbcdde466827642ebd795a5ba66077cfefd099d24daab4902e4d8a592d1cf5008", + "logs": [], + "blockNumber": 6672541, + "cumulativeGasUsed": "4968848", + "status": 1, + "byzantium": true + }, + "args": ["0xA0Cc0CC82d945D96D4F481A62C968AfCCea1C54F"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/goerli/TaskTreasuryUpgradable_Proxy.json b/deployments/goerli/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..f490ba75 --- /dev/null +++ b/deployments/goerli/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,217 @@ +{ + "address": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "transactionIndex": 2, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000800000000000000000000000000020000000000810000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000000000010000000000000000000000000000020000000000000000000000400000000000002000000000000010000100000000000", + "blockHash": "0x6f3f809eea5f9bf9c72a445cf94c20752e497d7403dae2c730f106b7f0ee278e", + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 6672542, + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "address": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000003f2b8c176a61845327f442a91160c14254dc2a91" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x6f3f809eea5f9bf9c72a445cf94c20752e497d7403dae2c730f106b7f0ee278e" + }, + { + "transactionIndex": 2, + "blockNumber": 6672542, + "transactionHash": "0xf930109c68d3d5b6f82cd6cc33e10b21b73babe11bde724cbaf890850eb9a4dc", + "address": "0xF381dfd7a139caaB83c26140e5595C0b85DDadCd", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x6f3f809eea5f9bf9c72a445cf94c20752e497d7403dae2c730f106b7f0ee278e" + } + ], + "blockNumber": 6672542, + "cumulativeGasUsed": "855814", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3F2b8C176a61845327f442a91160C14254dc2A91", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/goerli/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/goerli/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/goerli/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/mainnet/Ops.json b/deployments/mainnet/Ops.json index c23c0e24..bcfa1f18 100644 --- a/deployments/mainnet/Ops.json +++ b/deployments/mainnet/Ops.json @@ -2263,7 +2263,7 @@ } } ], - "implementation": "0xcB62d497Cd7C74eCC6bA367125bd1ee83c3dB2F8", + "implementation": "0x3C8859CEE19d369cEAC29eF6306106A92dD1BCAb", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/mainnet/Ops_Implementation.json b/deployments/mainnet/Ops_Implementation.json index ce01d582..2cd1f83b 100644 --- a/deployments/mainnet/Ops_Implementation.json +++ b/deployments/mainnet/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xcB62d497Cd7C74eCC6bA367125bd1ee83c3dB2F8", + "address": "0x3C8859CEE19d369cEAC29eF6306106A92dD1BCAb", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0xb4e45654f062d3cd15a49482239f0fa1f36adf0c10ad24762ea08431b0db8fca", + "transactionHash": "0xf88c69bbbdbdac372933663262fc90dea61eca21615c57b4f7a69c426b7675ef", "receipt": { "to": null, - "from": "0xAabB54394E8dd61Dd70897E9c80be8de7C64A895", - "contractAddress": "0xcB62d497Cd7C74eCC6bA367125bd1ee83c3dB2F8", - "transactionIndex": 174, - "gasUsed": "2650204", + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x3C8859CEE19d369cEAC29eF6306106A92dD1BCAb", + "transactionIndex": 16, + "gasUsed": "2673350", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x546357a0dd7eea202b24620668477f626c455f7d90a73e57029e84fc45004ac9", - "transactionHash": "0xb4e45654f062d3cd15a49482239f0fa1f36adf0c10ad24762ea08431b0db8fca", + "blockHash": "0x70710652c04aab07b15b85db9a24aa96f15cedc1e62fd5e9af5aabf70535ca94", + "transactionHash": "0xf88c69bbbdbdac372933663262fc90dea61eca21615c57b4f7a69c426b7675ef", "logs": [], - "blockNumber": 14140432, - "cumulativeGasUsed": "13274833", + "blockNumber": 14568862, + "cumulativeGasUsed": "4237247", "status": 1, "byzantium": true }, "args": [ "0x3caca7b48d0573d793d3b0279b5f0029180e83b6", - "0x66e2F69df68C8F56837142bE2E8C290EfE76DA9f" + "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/mainnet/TaskTreasuryUpgradable.json b/deployments/mainnet/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..73b77861 --- /dev/null +++ b/deployments/mainnet/TaskTreasuryUpgradable.json @@ -0,0 +1,647 @@ +{ + "address": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "transactionIndex": 53, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000010000000000000020020000000100000000000800000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000000000010000000000000000000000004000020000000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0xa323614c4ed90099ad07e2b028d4b690c99419163f0bdae07bf364bfb85efb13", + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "logs": [ + { + "transactionIndex": 53, + "blockNumber": 14543753, + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "address": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000063f33cb7eb6e6707b2d8dd913e897398905a34fd" + ], + "data": "0x", + "logIndex": 67, + "blockHash": "0xa323614c4ed90099ad07e2b028d4b690c99419163f0bdae07bf364bfb85efb13" + }, + { + "transactionIndex": 53, + "blockNumber": 14543753, + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "address": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 68, + "blockHash": "0xa323614c4ed90099ad07e2b028d4b690c99419163f0bdae07bf364bfb85efb13" + } + ], + "blockNumber": 14543753, + "cumulativeGasUsed": "3702675", + "status": 1, + "byzantium": true + }, + "args": [ + "0x63f33CB7eB6e6707b2D8DD913E897398905A34Fd", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x00" + } + ] + }, + "implementation": "0x63f33CB7eB6e6707b2D8DD913E897398905A34Fd", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mainnet/TaskTreasuryUpgradable_Implementation.json b/deployments/mainnet/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..097e70a8 --- /dev/null +++ b/deployments/mainnet/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,749 @@ +{ + "address": "0x63f33CB7eB6e6707b2D8DD913E897398905A34Fd", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x5ba0efa971d1ad22837977ad2b5d6eb28e2013687b948e5de6db3865861e7ccc", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x63f33CB7eB6e6707b2D8DD913E897398905A34Fd", + "transactionIndex": 31, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x54184213699425c9d6ae707553dc4875d0d4df2ce0bc2eeb84f915b49baff796", + "transactionHash": "0x5ba0efa971d1ad22837977ad2b5d6eb28e2013687b948e5de6db3865861e7ccc", + "logs": [], + "blockNumber": 14543752, + "cumulativeGasUsed": "4935579", + "status": 1, + "byzantium": true + }, + "args": ["0x66e2F69df68C8F56837142bE2E8C290EfE76DA9f"], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/mainnet/TaskTreasuryUpgradable_Proxy.json b/deployments/mainnet/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..b17f2045 --- /dev/null +++ b/deployments/mainnet/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,218 @@ +{ + "address": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "transactionIndex": 53, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000010000000000000020020000000100000000000800000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000000000000000000000000000000000000000010000000000000000000000004000020000000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0xa323614c4ed90099ad07e2b028d4b690c99419163f0bdae07bf364bfb85efb13", + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "logs": [ + { + "transactionIndex": 53, + "blockNumber": 14543753, + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "address": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000063f33cb7eb6e6707b2d8dd913e897398905a34fd" + ], + "data": "0x", + "logIndex": 67, + "blockHash": "0xa323614c4ed90099ad07e2b028d4b690c99419163f0bdae07bf364bfb85efb13" + }, + { + "transactionIndex": 53, + "blockNumber": 14543753, + "transactionHash": "0x0c5269b64f60f9cd4303c97feb1ae32f712a3dc15ff99d9b187dedd7f193d678", + "address": "0x2807B4aE232b624023f87d0e237A3B1bf200Fd99", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 68, + "blockHash": "0xa323614c4ed90099ad07e2b028d4b690c99419163f0bdae07bf364bfb85efb13" + } + ], + "blockNumber": 14543753, + "cumulativeGasUsed": "3702675", + "status": 1, + "byzantium": true + }, + "args": [ + "0x63f33CB7eB6e6707b2D8DD913E897398905A34Fd", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mainnet/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/mainnet/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/mainnet/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/matic/Ops.json b/deployments/matic/Ops.json index 5615aa6d..d7b51192 100644 --- a/deployments/matic/Ops.json +++ b/deployments/matic/Ops.json @@ -2998,7 +2998,7 @@ } } ], - "implementation": "0x74C1f8Ce8f2c6d6C8946d8eEC15374f9A9C57F3A", + "implementation": "0xd9E28bad0337b634aD8c2a644570580eFa602579", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/matic/Ops_Implementation.json b/deployments/matic/Ops_Implementation.json index 5abceb31..74335f9b 100644 --- a/deployments/matic/Ops_Implementation.json +++ b/deployments/matic/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x1C2DBC2E8cfc14f69EDB4F75b250d2b5bae8Fc26", + "address": "0xd9E28bad0337b634aD8c2a644570580eFa602579", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,46 +605,47 @@ "type": "function" } ], - "transactionHash": "0x53fa9b1703c38072050e3000c971b597f97f5c83ca7a465222b7c8e1cf23e8f0", + "transactionHash": "0x6cbea43445a7c03ae03a87559d4ecf994c0febca8ba9a4c66fe874917b04ff01", "receipt": { "to": null, - "from": "0xAabB54394E8dd61Dd70897E9c80be8de7C64A895", - "contractAddress": "0x1C2DBC2E8cfc14f69EDB4F75b250d2b5bae8Fc26", - "transactionIndex": 19, - "gasUsed": "2650216", - "logsBloom": "0x00000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000108000000000000000000000000000000000000000000000000000000040800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000040000100000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000200100000", - "blockHash": "0x6ce4fe7fead392d11597a1c3e9545d109eac3dd3d84d7758fdfa0b40b87aa064", - "transactionHash": "0x53fa9b1703c38072050e3000c971b597f97f5c83ca7a465222b7c8e1cf23e8f0", + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xd9E28bad0337b634aD8c2a644570580eFa602579", + "transactionIndex": 68, + "gasUsed": "2673362", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000800000000000000000000000000000800000000000000000000100000000000100000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000080000000000000004000000000000000040001000000000000000000000000000000100000000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0xc99e9216fa3b556c46f250d1bdd43187b1991116f1262d4cd049e1ed9f44b539", + "transactionHash": "0x6cbea43445a7c03ae03a87559d4ecf994c0febca8ba9a4c66fe874917b04ff01", "logs": [ { - "transactionIndex": 19, - "blockNumber": 24545239, - "transactionHash": "0x53fa9b1703c38072050e3000c971b597f97f5c83ca7a465222b7c8e1cf23e8f0", + "transactionIndex": 68, + "blockNumber": 27036190, + "transactionHash": "0x6cbea43445a7c03ae03a87559d4ecf994c0febca8ba9a4c66fe874917b04ff01", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", - "0x000000000000000000000000aabb54394e8dd61dd70897e9c80be8de7c64a895", - "0x00000000000000000000000026c80cc193b27d73d2c40943acec77f4da2c5bd8" + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000b95d435df3f8b2a8d8b9c2b7c8766c9ae6ed8cc9" ], - "data": "0x000000000000000000000000000000000000000000000000016efe8a02ca6280000000000000000000000000000000000000000000000012071388b3eaef59e2000000000000000000000000000000000000000000000193403012f15b01a82a00000000000000000000000000000000000000000000001205a48a29e824f762000000000000000000000000000000000000000000000193419f117b5dcc0aaa", - "logIndex": 79, - "blockHash": "0x6ce4fe7fead392d11597a1c3e9545d109eac3dd3d84d7758fdfa0b40b87aa064" + "data": "0x0000000000000000000000000000000000000000000000000298d699a5f4ff2200000000000000000000000000000000000000000000000004b5878276669ad8000000000000000000000000000000000000000000002c6c826c496e37aeb845000000000000000000000000000000000000000000000000021cb0e8d0719bb6000000000000000000000000000000000000000000002c6c85052007dda3b767", + "logIndex": 295, + "blockHash": "0xc99e9216fa3b556c46f250d1bdd43187b1991116f1262d4cd049e1ed9f44b539" } ], - "blockNumber": 24545239, - "cumulativeGasUsed": "4609305", + "blockNumber": 27036190, + "cumulativeGasUsed": "14431199", "status": 1, "byzantium": true }, "args": [ "0x7598e84B2E114AB62CAB288CE5f7d5f6bad35BbA", - "0xA8a7BBe83960B29789d5CB06Dcd2e6C1DF20581C" + "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -765,7 +766,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -773,7 +774,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -781,15 +782,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -797,7 +798,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -805,12 +806,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -830,12 +831,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -844,12 +845,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -858,27 +859,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -886,7 +887,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -896,12 +897,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -909,7 +910,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/matic/TaskTreasuryUpgradable.json b/deployments/matic/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..1f139091 --- /dev/null +++ b/deployments/matic/TaskTreasuryUpgradable.json @@ -0,0 +1,661 @@ +{ + "address": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "transactionIndex": 21, + "gasUsed": "782862", + "logsBloom": "0x00100000000020010010000000000000000000000000000000000000000000000000000080000000000400000000000000008000000000000000000000000000000000000000000000000000000000800000000080000000000102000000000000000000020000000000000000000800000000000000008080000000000000000000000200000000000000000000000000000200000000000000000000000000200000000000000000000000000200000000000000000080000000000000004000000000000000000001000000000010000000000000000002100000000020000000000000000000000400000000000002000000000000010000000000100000", + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8", + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "logs": [ + { + "transactionIndex": 21, + "blockNumber": 26844707, + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "address": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000099d30a8b8700f6c7bf6aa61506b1e895fabc5e3a" + ], + "data": "0x", + "logIndex": 64, + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8" + }, + { + "transactionIndex": 21, + "blockNumber": 26844707, + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "address": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 65, + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8" + }, + { + "transactionIndex": 21, + "blockNumber": 26844707, + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000de8da1ee512529b6c61fe7c769affc160308dea2" + ], + "data": "0x000000000000000000000000000000000000000000000000007d2865910616b0000000000000000000000000000000000000000000000000054259979b9d9cd8000000000000000000000000000000000000000000000a9ba475d2905613b59c00000000000000000000000000000000000000000000000004c531320a978628000000000000000000000000000000000000000000000a9ba4f2faf5e719cc4c", + "logIndex": 66, + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8" + } + ], + "blockNumber": 26844707, + "cumulativeGasUsed": "3070512", + "status": 1, + "byzantium": true + }, + "args": [ + "0x99D30A8B8700f6C7bF6AA61506b1E895FAbc5E3A", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000004563918244f40000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x4563918244f40000" + } + ] + }, + "implementation": "0x99D30A8B8700f6C7bF6AA61506b1E895FAbc5E3A", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/matic/TaskTreasuryUpgradable_Implementation.json b/deployments/matic/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..9f40009e --- /dev/null +++ b/deployments/matic/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,764 @@ +{ + "address": "0x99D30A8B8700f6C7bF6AA61506b1E895FAbc5E3A", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x086a7c1a6c4817dbdd1f509af95cacd706512ee7a2d9a77025c438c901da2d1b", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x99D30A8B8700f6C7bF6AA61506b1E895FAbc5E3A", + "transactionIndex": 20, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000080000000000100000000000000000000000000000000000000000000000000000000008080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000080000000000000004000000000000000000001000000000000000000000000000002100000000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0x5971620dc307f356a19656bcbf64774e7329e141fda8cfa241c07b9f33680982", + "transactionHash": "0x086a7c1a6c4817dbdd1f509af95cacd706512ee7a2d9a77025c438c901da2d1b", + "logs": [ + { + "transactionIndex": 20, + "blockNumber": 26844699, + "transactionHash": "0x086a7c1a6c4817dbdd1f509af95cacd706512ee7a2d9a77025c438c901da2d1b", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000de8da1ee512529b6c61fe7c769affc160308dea2" + ], + "data": "0x000000000000000000000000000000000000000000000000020ebb936f5bd4610000000000000000000000000000000000000000000000000751152c49b30ed8000000000000000000000000000000000000000000000a9b642ccf08054ca2c000000000000000000000000000000000000000000000000005425998da573a77000000000000000000000000000000000000000000000a9b663b8a9b74a87721", + "logIndex": 97, + "blockHash": "0x5971620dc307f356a19656bcbf64774e7329e141fda8cfa241c07b9f33680982" + } + ], + "blockNumber": 26844699, + "cumulativeGasUsed": "7317323", + "status": 1, + "byzantium": true + }, + "args": ["0xA8a7BBe83960B29789d5CB06Dcd2e6C1DF20581C"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/matic/TaskTreasuryUpgradable_Proxy.json b/deployments/matic/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..b13ab249 --- /dev/null +++ b/deployments/matic/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,232 @@ +{ + "address": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "transactionIndex": 21, + "gasUsed": "782862", + "logsBloom": "0x00100000000020010010000000000000000000000000000000000000000000000000000080000000000400000000000000008000000000000000000000000000000000000000000000000000000000800000000080000000000102000000000000000000020000000000000000000800000000000000008080000000000000000000000200000000000000000000000000000200000000000000000000000000200000000000000000000000000200000000000000000080000000000000004000000000000000000001000000000010000000000000000002100000000020000000000000000000000400000000000002000000000000010000000000100000", + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8", + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "logs": [ + { + "transactionIndex": 21, + "blockNumber": 26844707, + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "address": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000099d30a8b8700f6c7bf6aa61506b1e895fabc5e3a" + ], + "data": "0x", + "logIndex": 64, + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8" + }, + { + "transactionIndex": 21, + "blockNumber": 26844707, + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "address": "0x32DC6700AC87f6300277a63b0A4fDf132A8392bd", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 65, + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8" + }, + { + "transactionIndex": 21, + "blockNumber": 26844707, + "transactionHash": "0x2ec5fd0b49a722e5c0cb4cad6b65573dbf7369557c17f76829655d4ea3ca98e3", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000de8da1ee512529b6c61fe7c769affc160308dea2" + ], + "data": "0x000000000000000000000000000000000000000000000000007d2865910616b0000000000000000000000000000000000000000000000000054259979b9d9cd8000000000000000000000000000000000000000000000a9ba475d2905613b59c00000000000000000000000000000000000000000000000004c531320a978628000000000000000000000000000000000000000000000a9ba4f2faf5e719cc4c", + "logIndex": 66, + "blockHash": "0x1dac9a7170c838e64e6a506d5fa49ef53d28fef72b80a7006b7d6e4a376efcb8" + } + ], + "blockNumber": 26844707, + "cumulativeGasUsed": "3070512", + "status": 1, + "byzantium": true + }, + "args": [ + "0x99D30A8B8700f6C7bF6AA61506b1E895FAbc5E3A", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000004563918244f40000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/matic/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/matic/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/matic/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/mumbai/.chainId b/deployments/mumbai/.chainId new file mode 100644 index 00000000..d7e2f72c --- /dev/null +++ b/deployments/mumbai/.chainId @@ -0,0 +1 @@ +80001 \ No newline at end of file diff --git a/deployments/mumbai/Counter.json b/deployments/mumbai/Counter.json new file mode 100644 index 00000000..39fec858 --- /dev/null +++ b/deployments/mumbai/Counter.json @@ -0,0 +1,169 @@ +{ + "address": "0x04bDBB7eF8C17117d8Ef884029c268b7BecB2a19", + "abi": [ + { + "inputs": [ + { + "internalType": "address payable", + "name": "_ops", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "ETH", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "count", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gelato", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseCount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastExecuted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ops", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x08dcffe68d90fa848ca5e8fa09373e52da6f55b4313263fa813a7ba2cc0bba50", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x04bDBB7eF8C17117d8Ef884029c268b7BecB2a19", + "transactionIndex": 14, + "gasUsed": "380258", + "logsBloom": "0x00000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000020000000000000000001000000000080000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0x5ad8baa4deefec863aab70cdbdf383eb49fc9f4d2d61a02328b47ce6d7fd2529", + "transactionHash": "0x08dcffe68d90fa848ca5e8fa09373e52da6f55b4313263fa813a7ba2cc0bba50", + "logs": [ + { + "transactionIndex": 14, + "blockNumber": 25916600, + "transactionHash": "0x08dcffe68d90fa848ca5e8fa09373e52da6f55b4313263fa813a7ba2cc0bba50", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000c26880a0af2ea0c7e8130e6ec47af756465452e8" + ], + "data": "0x000000000000000000000000000000000000000000000000000206c392b93672000000000000000000000000000000000000000000000005726fb7ad8bd17b02000000000000000000000000000000000000000000000abd7541588cffbf0a55000000000000000000000000000000000000000000000005726db0e9f9184490000000000000000000000000000000000000000000000abd75435f50927840c7", + "logIndex": 44, + "blockHash": "0x5ad8baa4deefec863aab70cdbdf383eb49fc9f4d2d61a02328b47ce6d7fd2529" + } + ], + "blockNumber": 25916600, + "cumulativeGasUsed": "1682945", + "status": 1, + "byzantium": true + }, + "args": ["0xB3f5503f93d5Ef84b06993a1975B9D21B962892F"], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_ops\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"ETH\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gelato\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"increaseCount\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastExecuted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ops\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/examples/withTreasury/Counter.sol\":\"Counter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"contracts/examples/withTreasury/Counter.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {OpsReady} from \\\"../../vendor/gelato/OpsReady.sol\\\";\\n\\ncontract Counter is OpsReady {\\n uint256 public count;\\n uint256 public lastExecuted;\\n\\n // solhint-disable-next-line no-empty-blocks\\n constructor(address payable _ops) OpsReady(_ops) {}\\n\\n // solhint-disable not-rely-on-time\\n function increaseCount(uint256 amount) external onlyOps {\\n require(\\n ((block.timestamp - lastExecuted) > 180),\\n \\\"Counter: increaseCount: Time not elapsed\\\"\\n );\\n\\n count += amount;\\n lastExecuted = block.timestamp;\\n }\\n}\\n\",\"keccak256\":\"0x437a443cff8e608da29d9adfa1725ae500a4c5104444774fc9ad7e3540110816\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/OpsReady.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\ninterface IOps {\\n function gelato() external view returns (address payable);\\n}\\n\\nabstract contract OpsReady {\\n address public immutable ops;\\n address payable public immutable gelato;\\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n modifier onlyOps() {\\n require(msg.sender == ops, \\\"OpsReady: onlyOps\\\");\\n _;\\n }\\n\\n constructor(address _ops) {\\n ops = _ops;\\n gelato = IOps(_ops).gelato();\\n }\\n\\n function _transfer(uint256 _amount, address _paymentToken) internal {\\n if (_paymentToken == ETH) {\\n (bool success, ) = gelato.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x72e76d3e3f7c5f0e2fda964314fd5a8a53e0e7988eec683271e33166399f8903\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b5060405161077938038061077983398181016040528101906100329190610173565b808073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1663573ea5756040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d69190610173565b73ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff168152505050506101a0565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061014082610115565b9050919050565b61015081610135565b811461015b57600080fd5b50565b60008151905061016d81610147565b92915050565b60006020828403121561018957610188610110565b5b60006101978482850161015e565b91505092915050565b60805160a0516105ad6101cc6000396000610227015260008181610127015261026301526105ad6000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806306661abd146100675780631c15ff771461008557806346d4adf2146100a3578063573ea575146100bf5780638322fff2146100dd578063e70abe92146100fb575b600080fd5b61006f610119565b60405161007c919061029e565b60405180910390f35b61008d61011f565b60405161009a919061029e565b60405180910390f35b6100bd60048036038101906100b891906102ea565b610125565b005b6100c7610225565b6040516100d49190610358565b60405180910390f35b6100e5610249565b6040516100f29190610394565b60405180910390f35b610103610261565b6040516101109190610394565b60405180910390f35b60005481565b60015481565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101aa9061040c565b60405180910390fd5b60b4600154426101c3919061045b565b11610203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101fa90610501565b60405180910390fd5b806000808282546102149190610521565b925050819055504260018190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000819050919050565b61029881610285565b82525050565b60006020820190506102b3600083018461028f565b92915050565b600080fd5b6102c781610285565b81146102d257600080fd5b50565b6000813590506102e4816102be565b92915050565b600060208284031215610300576102ff6102b9565b5b600061030e848285016102d5565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061034282610317565b9050919050565b61035281610337565b82525050565b600060208201905061036d6000830184610349565b92915050565b600061037e82610317565b9050919050565b61038e81610373565b82525050565b60006020820190506103a96000830184610385565b92915050565b600082825260208201905092915050565b7f4f707352656164793a206f6e6c794f7073000000000000000000000000000000600082015250565b60006103f66011836103af565b9150610401826103c0565b602082019050919050565b60006020820190508181036000830152610425816103e9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061046682610285565b915061047183610285565b9250828210156104845761048361042c565b5b828203905092915050565b7f436f756e7465723a20696e637265617365436f756e743a2054696d65206e6f7460008201527f20656c6170736564000000000000000000000000000000000000000000000000602082015250565b60006104eb6028836103af565b91506104f68261048f565b604082019050919050565b6000602082019050818103600083015261051a816104de565b9050919050565b600061052c82610285565b915061053783610285565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561056c5761056b61042c565b5b82820190509291505056fea2646970667358221220bc9a9c14a4bc05ec76ba63ef47f0a67259185ad2086a60004290feafd4f2112b64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c806306661abd146100675780631c15ff771461008557806346d4adf2146100a3578063573ea575146100bf5780638322fff2146100dd578063e70abe92146100fb575b600080fd5b61006f610119565b60405161007c919061029e565b60405180910390f35b61008d61011f565b60405161009a919061029e565b60405180910390f35b6100bd60048036038101906100b891906102ea565b610125565b005b6100c7610225565b6040516100d49190610358565b60405180910390f35b6100e5610249565b6040516100f29190610394565b60405180910390f35b610103610261565b6040516101109190610394565b60405180910390f35b60005481565b60015481565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101aa9061040c565b60405180910390fd5b60b4600154426101c3919061045b565b11610203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101fa90610501565b60405180910390fd5b806000808282546102149190610521565b925050819055504260018190555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000819050919050565b61029881610285565b82525050565b60006020820190506102b3600083018461028f565b92915050565b600080fd5b6102c781610285565b81146102d257600080fd5b50565b6000813590506102e4816102be565b92915050565b600060208284031215610300576102ff6102b9565b5b600061030e848285016102d5565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061034282610317565b9050919050565b61035281610337565b82525050565b600060208201905061036d6000830184610349565b92915050565b600061037e82610317565b9050919050565b61038e81610373565b82525050565b60006020820190506103a96000830184610385565b92915050565b600082825260208201905092915050565b7f4f707352656164793a206f6e6c794f7073000000000000000000000000000000600082015250565b60006103f66011836103af565b9150610401826103c0565b602082019050919050565b60006020820190508181036000830152610425816103e9565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061046682610285565b915061047183610285565b9250828210156104845761048361042c565b5b828203905092915050565b7f436f756e7465723a20696e637265617365436f756e743a2054696d65206e6f7460008201527f20656c6170736564000000000000000000000000000000000000000000000000602082015250565b60006104eb6028836103af565b91506104f68261048f565b604082019050919050565b6000602082019050818103600083015261051a816104de565b9050919050565b600061052c82610285565b915061053783610285565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561056c5761056b61042c565b5b82820190509291505056fea2646970667358221220bc9a9c14a4bc05ec76ba63ef47f0a67259185ad2086a60004290feafd4f2112b64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 2616, + "contract": "contracts/examples/withTreasury/Counter.sol:Counter", + "label": "count", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 2618, + "contract": "contracts/examples/withTreasury/Counter.sol:Counter", + "label": "lastExecuted", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "types": { + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/mumbai/CounterResolver.json b/deployments/mumbai/CounterResolver.json new file mode 100644 index 00000000..ee03167e --- /dev/null +++ b/deployments/mumbai/CounterResolver.json @@ -0,0 +1,99 @@ +{ + "address": "0xE196330228CdE3Bb6b29413f32A95C45ACcF4952", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_counter", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "COUNTER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "checker", + "outputs": [ + { + "internalType": "bool", + "name": "canExec", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "execPayload", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x1ed37ebf7432679e45f2775cd318e465715ec1a11a9dfd6e6fe227e39a0ce051", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xE196330228CdE3Bb6b29413f32A95C45ACcF4952", + "transactionIndex": 40, + "gasUsed": "287549", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000080000000000000004000000000000000000001000000000000000000000000000000100040000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0xf91fd213e2f3729537cd456e91f62e5eb48ce47d8b8b8d84a18bfd862ecaaf2d", + "transactionHash": "0x1ed37ebf7432679e45f2775cd318e465715ec1a11a9dfd6e6fe227e39a0ce051", + "logs": [ + { + "transactionIndex": 40, + "blockNumber": 25916612, + "transactionHash": "0x1ed37ebf7432679e45f2775cd318e465715ec1a11a9dfd6e6fe227e39a0ce051", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x0000000000000000000000000000000000000000000000000001884954234ce8000000000000000000000000000000000000000000000005726db0e9f8e40c1e000000000000000000000000000000000000000000001076457fc41c5a3797ab000000000000000000000000000000000000000000000005726c28a0a4c0bf3600000000000000000000000000000000000000000000107645814c65ae5ae493", + "logIndex": 256, + "blockHash": "0xf91fd213e2f3729537cd456e91f62e5eb48ce47d8b8b8d84a18bfd862ecaaf2d" + } + ], + "blockNumber": 25916612, + "cumulativeGasUsed": "11623932", + "status": 1, + "byzantium": true + }, + "args": ["0x04bDBB7eF8C17117d8Ef884029c268b7BecB2a19"], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_counter\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"COUNTER\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"checker\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"canExec\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"execPayload\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/examples/withTreasury/CounterResolver.sol\":\"CounterResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/examples/withTreasury/CounterResolver.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {IResolver} from \\\"../../interfaces/IResolver.sol\\\";\\n\\ninterface ICounter {\\n function increaseCount(uint256 amount) external;\\n\\n function lastExecuted() external view returns (uint256);\\n}\\n\\ncontract CounterResolver is IResolver {\\n // solhint-disable var-name-mixedcase\\n address public immutable COUNTER;\\n\\n constructor(address _counter) {\\n COUNTER = _counter;\\n }\\n\\n function checker()\\n external\\n view\\n override\\n returns (bool canExec, bytes memory execPayload)\\n {\\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\\n\\n // solhint-disable not-rely-on-time\\n canExec = (block.timestamp - lastExecuted) > 180;\\n\\n execPayload = abi.encodeWithSelector(\\n ICounter.increaseCount.selector,\\n uint256(100)\\n );\\n }\\n}\\n\",\"keccak256\":\"0xffc783b039ac716a32986bc9c4c3a268db5a6176ed8a6379519ebf733ab1e5fa\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/IResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IResolver {\\n function checker()\\n external\\n view\\n returns (bool canExec, bytes memory execPayload);\\n}\\n\",\"keccak256\":\"0xcc9472c4ce4661c9260b3ebb5fa90ae55f83de88c30ae0bdd56c30e25ea6cedd\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b50604051610549380380610549833981810160405281019061003291906100cf565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506100fc565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061009c82610071565b9050919050565b6100ac81610091565b81146100b757600080fd5b50565b6000815190506100c9816100a3565b92915050565b6000602082840312156100e5576100e461006c565b5b60006100f3848285016100ba565b91505092915050565b60805161042d61011c60003960008181607a015260a4015261042d6000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806399b705791461003b578063cf5303cf14610059575b600080fd5b610043610078565b6040516100509190610203565b60405180910390f35b61006161009c565b60405161006f9291906102d2565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631c15ff776040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610131919061033d565b905060b481426101419190610399565b1192506346d4adf260e01b606460405160240161015e91906103dc565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509150509091565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101ed826101c2565b9050919050565b6101fd816101e2565b82525050565b600060208201905061021860008301846101f4565b92915050565b60008115159050919050565b6102338161021e565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610273578082015181840152602081019050610258565b83811115610282576000848401525b50505050565b6000601f19601f8301169050919050565b60006102a482610239565b6102ae8185610244565b93506102be818560208601610255565b6102c781610288565b840191505092915050565b60006040820190506102e7600083018561022a565b81810360208301526102f98184610299565b90509392505050565b600080fd5b6000819050919050565b61031a81610307565b811461032557600080fd5b50565b60008151905061033781610311565b92915050565b60006020828403121561035357610352610302565b5b600061036184828501610328565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006103a482610307565b91506103af83610307565b9250828210156103c2576103c161036a565b5b828203905092915050565b6103d681610307565b82525050565b60006020820190506103f160008301846103cd565b9291505056fea26469706673582212202824e72bb21f173897e2321bee40f74e5148bf69e1e83319ea97ff9284a6de2664736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806399b705791461003b578063cf5303cf14610059575b600080fd5b610043610078565b6040516100509190610203565b60405180910390f35b61006161009c565b60405161006f9291906102d2565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b6000606060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631c15ff776040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610131919061033d565b905060b481426101419190610399565b1192506346d4adf260e01b606460405160240161015e91906103dc565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509150509091565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101ed826101c2565b9050919050565b6101fd816101e2565b82525050565b600060208201905061021860008301846101f4565b92915050565b60008115159050919050565b6102338161021e565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610273578082015181840152602081019050610258565b83811115610282576000848401525b50505050565b6000601f19601f8301169050919050565b60006102a482610239565b6102ae8185610244565b93506102be818560208601610255565b6102c781610288565b840191505092915050565b60006040820190506102e7600083018561022a565b81810360208301526102f98184610299565b90509392505050565b600080fd5b6000819050919050565b61031a81610307565b811461032557600080fd5b50565b60008151905061033781610311565b92915050565b60006020828403121561035357610352610302565b5b600061036184828501610328565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006103a482610307565b91506103af83610307565b9250828210156103c2576103c161036a565b5b828203905092915050565b6103d681610307565b82525050565b60006020820190506103f160008301846103cd565b9291505056fea26469706673582212202824e72bb21f173897e2321bee40f74e5148bf69e1e83319ea97ff9284a6de2664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mumbai/Forwarder.json b/deployments/mumbai/Forwarder.json new file mode 100644 index 00000000..67903969 --- /dev/null +++ b/deployments/mumbai/Forwarder.json @@ -0,0 +1,81 @@ +{ + "address": "0x4055cb250Ec8d539C5222EAa71fa7e30Fe94f8e9", + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "execData", + "type": "bytes" + } + ], + "name": "checker", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "transactionHash": "0x8ab3051dc70458814956016d60f6ec57ac20e5a6c8e5b9cf98fb7037b8b6946e", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x4055cb250Ec8d539C5222EAa71fa7e30Fe94f8e9", + "transactionIndex": 37, + "gasUsed": "224858", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000080000000000000004000000000000000000001000000000000000000000000000000100040000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0x2d64fdb2ff8927e8af31a791a9a11b0fc6578c08ba6272e9c39fd920391e63cc", + "transactionHash": "0x8ab3051dc70458814956016d60f6ec57ac20e5a6c8e5b9cf98fb7037b8b6946e", + "logs": [ + { + "transactionIndex": 37, + "blockNumber": 25916617, + "transactionHash": "0x8ab3051dc70458814956016d60f6ec57ac20e5a6c8e5b9cf98fb7037b8b6946e", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x000000000000000000000000000000000000000000000000000132c2bff1672a000000000000000000000000000000000000000000000005726c28a0a4907b9700000000000000000000000000000000000000000000107659a38c49f4002a50000000000000000000000000000000000000000000000005726af5dde49f146d00000000000000000000000000000000000000000000107659a4bf0cb3f1917a", + "logIndex": 248, + "blockHash": "0x2d64fdb2ff8927e8af31a791a9a11b0fc6578c08ba6272e9c39fd920391e63cc" + } + ], + "blockNumber": 25916617, + "cumulativeGasUsed": "7509405", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"}],\"name\":\"checker\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Forwarder.sol\":\"Forwarder\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/Forwarder.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\ncontract Forwarder {\\n function checker(bytes memory execData)\\n external\\n pure\\n returns (bool, bytes memory)\\n {\\n return (true, execData);\\n }\\n}\\n\",\"keccak256\":\"0x33f636585c88ece73a8b855a0e21d513688295ec0ad81b6a5a36786e2093e2a0\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061031d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e931fd5b14610030575b600080fd5b61004a600480360381019061004591906101cb565b610061565b6040516100589291906102b7565b60405180910390f35b6000606060018391509150915091565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100d88261008f565b810181811067ffffffffffffffff821117156100f7576100f66100a0565b5b80604052505050565b600061010a610071565b905061011682826100cf565b919050565b600067ffffffffffffffff821115610136576101356100a0565b5b61013f8261008f565b9050602081019050919050565b82818337600083830152505050565b600061016e6101698461011b565b610100565b90508281526020810184848401111561018a5761018961008a565b5b61019584828561014c565b509392505050565b600082601f8301126101b2576101b1610085565b5b81356101c284826020860161015b565b91505092915050565b6000602082840312156101e1576101e061007b565b5b600082013567ffffffffffffffff8111156101ff576101fe610080565b5b61020b8482850161019d565b91505092915050565b60008115159050919050565b61022981610214565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561026957808201518184015260208101905061024e565b83811115610278576000848401525b50505050565b60006102898261022f565b610293818561023a565b93506102a381856020860161024b565b6102ac8161008f565b840191505092915050565b60006040820190506102cc6000830185610220565b81810360208301526102de818461027e565b9050939250505056fea2646970667358221220807813d29c8f4132c1b1137f4dd5f96daeeaeb5392a0c0988d69a0dc77e0c8f464736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063e931fd5b14610030575b600080fd5b61004a600480360381019061004591906101cb565b610061565b6040516100589291906102b7565b60405180910390f35b6000606060018391509150915091565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100d88261008f565b810181811067ffffffffffffffff821117156100f7576100f66100a0565b5b80604052505050565b600061010a610071565b905061011682826100cf565b919050565b600067ffffffffffffffff821115610136576101356100a0565b5b61013f8261008f565b9050602081019050919050565b82818337600083830152505050565b600061016e6101698461011b565b610100565b90508281526020810184848401111561018a5761018961008a565b5b61019584828561014c565b509392505050565b600082601f8301126101b2576101b1610085565b5b81356101c284826020860161015b565b91505092915050565b6000602082840312156101e1576101e061007b565b5b600082013567ffffffffffffffff8111156101ff576101fe610080565b5b61020b8482850161019d565b91505092915050565b60008115159050919050565b61022981610214565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561026957808201518184015260208101905061024e565b83811115610278576000848401525b50505050565b60006102898261022f565b610293818561023a565b93506102a381856020860161024b565b6102ac8161008f565b840191505092915050565b60006040820190506102cc6000830185610220565b81810360208301526102de818461027e565b9050939250505056fea2646970667358221220807813d29c8f4132c1b1137f4dd5f96daeeaeb5392a0c0988d69a0dc77e0c8f464736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mumbai/Ops.json b/deployments/mumbai/Ops.json new file mode 100644 index 00000000..c180a250 --- /dev/null +++ b/deployments/mumbai/Ops.json @@ -0,0 +1,821 @@ +{ + "address": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "txFee", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "execAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "execData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "callSuccess", + "type": "bool" + } + ], + "name": "ExecSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "taskCreator", + "type": "address" + } + ], + "name": "TaskCancelled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "taskCreator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "execAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "address", + "name": "resolverAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "resolverData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bool", + "name": "useTaskTreasuryFunds", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "resolverHash", + "type": "bytes32" + } + ], + "name": "TaskCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint128", + "name": "nextExec", + "type": "uint128" + }, + { + "indexed": true, + "internalType": "uint128", + "name": "interval", + "type": "uint128" + } + ], + "name": "TimerSet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_taskId", + "type": "bytes32" + } + ], + "name": "cancelTask", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + } + ], + "name": "createTask", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + } + ], + "name": "createTaskNoPrepayment", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_startTime", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "_interval", + "type": "uint128" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useTreasury", + "type": "bool" + } + ], + "name": "createTimedTask", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_txFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_taskCreator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useTaskTreasuryFunds", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_revertOnFailure", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "_resolverHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_execData", + "type": "bytes" + } + ], + "name": "exec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "execAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + } + ], + "name": "getResolverHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_func", + "type": "string" + } + ], + "name": "getSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_taskCreator", + "type": "address" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_useTaskTreasuryFunds", + "type": "bool" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_resolverHash", + "type": "bytes32" + } + ], + "name": "getTaskId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "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": "taskCreator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taskTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasuryUpgradable", + "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" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "transactionIndex": 44, + "gasUsed": "641923", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000004000000400000000000000008000000000000000000000000000000000000000000000000000000000800401000000000000000100000000004000000000020000000000000000800800000000000000000080000000000000410000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000200000000000000000080000040000000004000000000000000000001000000000000000000000000000000100040000020000000000000001000000400000000000002000000000000010000000000100000", + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1", + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 25914256, + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "address": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008ab6adbc1fec4f18617c9b889f5ce7f28401b8db" + ], + "data": "0x", + "logIndex": 150, + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1" + }, + { + "transactionIndex": 44, + "blockNumber": 25914256, + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "address": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 151, + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1" + }, + { + "transactionIndex": 44, + "blockNumber": 25914256, + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000036bbd04a8a40600000000000000000000000000000000000000000000000006c002cd6191a1cf00000000000000000000000000000000000000000000106a81b472024c21634d00000000000000000000000000000000000000000000000006bc97105ce8fdc900000000000000000000000000000000000000000000106a81b7ddbf50ca0753", + "logIndex": 152, + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1" + } + ], + "blockNumber": 25914256, + "cumulativeGasUsed": "6689412", + "status": 1, + "byzantium": true + }, + "args": [ + "0x8aB6aDbC1fec4F18617C9B889F5cE7F28401B8dB", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0x" + ], + "numDeployments": 1, + "solcInputHash": "41a8600e180880fe88609322a6b2ac21", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/proxy/EIP173Proxy.sol\":\"EIP173Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/proxy/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setOwner(ownerAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function owner() external view returns (address) {\\n return _owner();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferOwnership(address newOwner) external onlyOwner {\\n _setOwner(newOwner);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyOwner {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyOwner() {\\n require(msg.sender == _owner(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _owner() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\\n }\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address previousOwner = _owner();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\\n }\\n emit OwnershipTransferred(previousOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xb9c14a66c8a4eefabca13cc8dd8133c1587909bb1124fa793c50ab46358b63e4\",\"license\":\"MIT\"},\"solc_0.8/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data) internal {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\\n }\\n\\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x68c8cf1a340a53d31de8ed808bb66d64e83d50b20d80a0b2dff6aba903cebc98\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260405162000ccc38038062000ccc8339810160408190526200002691620001fc565b62000032838262000046565b6200003d8262000128565b505050620002fa565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8054908390556040516001600160a01b0380851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511562000123576000836001600160a01b031683604051620000ca9190620002dc565b600060405180830381855af49150503d806000811462000107576040519150601f19603f3d011682016040523d82523d6000602084013e6200010c565b606091505b505090508062000121573d806000803e806000fd5b505b505050565b60006200014260008051602062000cac8339815191525490565b90508160008051602062000cac83398151915255816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b80516001600160a01b0381168114620001b257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ea578181015183820152602001620001d0565b83811115620001215750506000910152565b6000806000606084860312156200021257600080fd5b6200021d846200019a565b92506200022d602085016200019a565b60408501519092506001600160401b03808211156200024b57600080fd5b818601915086601f8301126200026057600080fd5b815181811115620002755762000275620001b7565b604051601f8201601f19908116603f01168101908382118183101715620002a057620002a0620001b7565b81604052828152896020848701011115620002ba57600080fd5b620002cd836020830160208801620001cd565b80955050505050509250925092565b60008251620002f0818460208701620001cd565b9190910192915050565b6109a2806200030a6000396000f3fe60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101295780638da5cb5b1461013c578063f2fde38b14610176576100ca565b806301ffc9a7146100d45780633659cfe614610109576100ca565b366100ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a454354454400000000000000000000000000000000000060448201526064015b60405180910390fd5b6100d2610196565b005b3480156100e057600080fd5b506100f46100ef366004610806565b6101e1565b60405190151581526020015b60405180910390f35b34801561011557600080fd5b506100d2610124366004610871565b6103af565b6100d261013736600461088c565b610481565b34801561014857600080fd5b5061015161057c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b34801561018257600080fd5b506100d2610191366004610871565b6105ab565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156101d7578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061027457507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561028157506001919050565b7fffffffff0000000000000000000000000000000000000000000000000000000080831614156102b357506000919050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa92505050801561039b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526103989181019061090f565b60015b6103a85750600092915050565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e816040518060200160405280600081525061066a565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b6105778383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066a92505050565b505050565b60006105a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e81610759565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a38151156105775760008373ffffffffffffffffffffffffffffffffffffffff16836040516107059190610931565b600060405180830381855af49150503d8060008114610740576040519150601f19603f3d011682016040523d82523d6000602084013e610745565b606091505b50509050806101db573d806000803e806000fd5b60006107837fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020828403121561081857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146103a857600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461086c57600080fd5b919050565b60006020828403121561088357600080fd5b6103a882610848565b6000806000604084860312156108a157600080fd5b6108aa84610848565b9250602084013567ffffffffffffffff808211156108c757600080fd5b818601915086601f8301126108db57600080fd5b8135818111156108ea57600080fd5b8760208285010111156108fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561092157600080fd5b815180151581146103a857600080fd5b6000825160005b818110156109525760208186018101518583015201610938565b81811115610961576000828501525b50919091019291505056fea2646970667358221220d2ec357659da93a66b21590e3c56e508e51e4de5703da4d1f7ba0b98d9e047f964736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101295780638da5cb5b1461013c578063f2fde38b14610176576100ca565b806301ffc9a7146100d45780633659cfe614610109576100ca565b366100ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a454354454400000000000000000000000000000000000060448201526064015b60405180910390fd5b6100d2610196565b005b3480156100e057600080fd5b506100f46100ef366004610806565b6101e1565b60405190151581526020015b60405180910390f35b34801561011557600080fd5b506100d2610124366004610871565b6103af565b6100d261013736600461088c565b610481565b34801561014857600080fd5b5061015161057c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b34801561018257600080fd5b506100d2610191366004610871565b6105ab565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156101d7578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061027457507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561028157506001919050565b7fffffffff0000000000000000000000000000000000000000000000000000000080831614156102b357506000919050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa92505050801561039b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526103989181019061090f565b60015b6103a85750600092915050565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e816040518060200160405280600081525061066a565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b6105778383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066a92505050565b505050565b60006105a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e81610759565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a38151156105775760008373ffffffffffffffffffffffffffffffffffffffff16836040516107059190610931565b600060405180830381855af49150503d8060008114610740576040519150601f19603f3d011682016040523d82523d6000602084013e610745565b606091505b50509050806101db573d806000803e806000fd5b60006107837fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020828403121561081857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146103a857600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461086c57600080fd5b919050565b60006020828403121561088357600080fd5b6103a882610848565b6000806000604084860312156108a157600080fd5b6108aa84610848565b9250602084013567ffffffffffffffff808211156108c757600080fd5b818601915086601f8301126108db57600080fd5b8135818111156108ea57600080fd5b8760208285010111156108fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561092157600080fd5b815180151581146103a857600080fd5b6000825160005b818110156109525760208186018101518583015201610938565b81811115610961576000828501525b50919091019291505056fea2646970667358221220d2ec357659da93a66b21590e3c56e508e51e4de5703da4d1f7ba0b98d9e047f964736f6c634300080a0033", + "implementation": "0x8aB6aDbC1fec4F18617C9B889F5cE7F28401B8dB", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mumbai/Ops_Implementation.json b/deployments/mumbai/Ops_Implementation.json new file mode 100644 index 00000000..76dc9ec6 --- /dev/null +++ b/deployments/mumbai/Ops_Implementation.json @@ -0,0 +1,935 @@ +{ + "address": "0x8aB6aDbC1fec4F18617C9B889F5cE7F28401B8dB", + "abi": [ + { + "inputs": [ + { + "internalType": "address payable", + "name": "_gelato", + "type": "address" + }, + { + "internalType": "contract ITaskTreasuryUpgradable", + "name": "_taskTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "txFee", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "execAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "execData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bool", + "name": "callSuccess", + "type": "bool" + } + ], + "name": "ExecSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "taskCreator", + "type": "address" + } + ], + "name": "TaskCancelled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "taskCreator", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "execAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + }, + { + "indexed": false, + "internalType": "address", + "name": "resolverAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "resolverData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bool", + "name": "useTaskTreasuryFunds", + "type": "bool" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "resolverHash", + "type": "bytes32" + } + ], + "name": "TaskCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "taskId", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "uint128", + "name": "nextExec", + "type": "uint128" + }, + { + "indexed": true, + "internalType": "uint128", + "name": "interval", + "type": "uint128" + } + ], + "name": "TimerSet", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_taskId", + "type": "bytes32" + } + ], + "name": "cancelTask", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + } + ], + "name": "createTask", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + } + ], + "name": "createTaskNoPrepayment", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint128", + "name": "_startTime", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "_interval", + "type": "uint128" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_execSelector", + "type": "bytes4" + }, + { + "internalType": "address", + "name": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useTreasury", + "type": "bool" + } + ], + "name": "createTimedTask", + "outputs": [ + { + "internalType": "bytes32", + "name": "task", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_txFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_taskCreator", + "type": "address" + }, + { + "internalType": "bool", + "name": "_useTaskTreasuryFunds", + "type": "bool" + }, + { + "internalType": "bool", + "name": "_revertOnFailure", + "type": "bool" + }, + { + "internalType": "bytes32", + "name": "_resolverHash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_execData", + "type": "bytes" + } + ], + "name": "exec", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "execAddresses", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "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": "_resolverAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_resolverData", + "type": "bytes" + } + ], + "name": "getResolverHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_func", + "type": "string" + } + ], + "name": "getSelector", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_taskCreator", + "type": "address" + }, + { + "internalType": "address", + "name": "_execAddress", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "_selector", + "type": "bytes4" + }, + { + "internalType": "bool", + "name": "_useTaskTreasuryFunds", + "type": "bool" + }, + { + "internalType": "address", + "name": "_feeToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_resolverHash", + "type": "bytes32" + } + ], + "name": "getTaskId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "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": "taskCreator", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "taskTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasuryUpgradable", + "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" + } + ], + "transactionHash": "0xe6998d95d8670fbfa00ba61cc2b13e5348c754a7e5108b3afa74543199b64a90", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x8aB6aDbC1fec4F18617C9B889F5cE7F28401B8dB", + "transactionIndex": 49, + "gasUsed": "2673362", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000080000000000000004000000000000000000001000000000000000000000000000000100040000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0x76e72c4024443cdd2788dbcb31998de3ccaaa3febe8335dc1f9aabbc74496a49", + "transactionHash": "0xe6998d95d8670fbfa00ba61cc2b13e5348c754a7e5108b3afa74543199b64a90", + "logs": [ + { + "transactionIndex": 49, + "blockNumber": 25914255, + "transactionHash": "0xe6998d95d8670fbfa00ba61cc2b13e5348c754a7e5108b3afa74543199b64a90", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x000000000000000000000000000000000000000000000000000e3f1ce4de23a400000000000000000000000000000000000000000000000006ce41ea48aadcef00000000000000000000000000000000000000000000106a808b23a5b93dc92c00000000000000000000000000000000000000000000000006c002cd63ccb94b00000000000000000000000000000000000000000000106a809962c29e1becd0", + "logIndex": 166, + "blockHash": "0x76e72c4024443cdd2788dbcb31998de3ccaaa3febe8335dc1f9aabbc74496a49" + } + ], + "blockNumber": 25914255, + "cumulativeGasUsed": "9051376", + "status": 1, + "byzantium": true + }, + "args": [ + "0x25aD59adbe00C2d80c86d01e2E05e1294DA84823", + "0x527a819db1eb0e34426297b03bae11F2f8B3A19E" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "cancelTask(bytes32)": { + "params": { + "_taskId": "The hash of the task, can be computed using getTaskId()" + } + }, + "createTask(address,bytes4,address,bytes)": { + "details": "Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops", + "params": { + "_execAddress": "On which contract should Gelato execute the transactions", + "_execSelector": "Which function Gelato should eecute on the _execAddress", + "_resolverAddress": "On which contract should Gelato check when to execute the tx", + "_resolverData": "Which data should be used to check on the Resolver when to execute the tx" + } + }, + "createTaskNoPrepayment(address,bytes4,address,bytes,address)": { + "details": "Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly", + "params": { + "_execAddress": "On which contract should Gelato execute the transactions", + "_execSelector": "Which function Gelato should eecute on the _execAddress", + "_feeToken": "Which token to use as fee payment", + "_resolverAddress": "On which contract should Gelato check when to execute the tx", + "_resolverData": "Which data should be used to check on the Resolver when to execute the tx" + } + }, + "createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)": { + "params": { + "_execAddress": "On which contract should Gelato execute the transactions", + "_execSelector": "Which function Gelato should eecute on the _execAddress", + "_feeToken": "Which token to use as fee payment", + "_interval": "After how many seconds should each task be executed", + "_resolverAddress": "On which contract should Gelato check when to execute the tx", + "_resolverData": "Which data should be used to check on the Resolver when to execute the tx", + "_startTime": "Timestamp when the first task should become executable. 0 for right now", + "_useTreasury": "True if Gelato should charge fees from TaskTreasury, false if not" + } + }, + "exec(uint256,address,address,bool,bool,bytes32,address,bytes)": { + "params": { + "_execAddress": "On which contract should Gelato execute the tx", + "_execData": "Data used to execute the tx, queried from the Resolver by Gelato", + "_feeToken": "Token used to pay for the execution. ETH = 0xeeeeee...", + "_revertOnFailure": "To revert or not if call to execAddress fails", + "_taskCreator": "On which contract should Gelato check when to execute the tx", + "_txFee": "Fee paid to Gelato for execution, deducted on the TaskTreasury", + "_useTaskTreasuryFunds": "If msg.sender's balance on TaskTreasury should pay for the tx" + } + }, + "getResolverHash(address,bytes)": { + "params": { + "_resolverAddress": "Address of resolver", + "_resolverData": "Data passed to resolver" + } + }, + "getSelector(string)": { + "details": "Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd", + "params": { + "_func": "String of the function you want the selector from" + } + }, + "getTaskId(address,address,bytes4,bool,address,bytes32)": { + "params": { + "_execAddress": "Address of the contract to be executed by Gelato", + "_feeToken": "FeeToken to use, address 0 if task treasury is used", + "_resolverHash": "hash of resolver address and data", + "_selector": "Function on the _execAddress which should be executed", + "_taskCreator": "Address of the task creator", + "_useTaskTreasuryFunds": "If msg.sender's balance on TaskTreasury should pay for the tx" + } + }, + "getTaskIdsByUser(address)": { + "params": { + "_taskCreator": "Address who created the task" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "cancelTask(bytes32)": { + "notice": "Cancel a task so that Gelato can no longer execute it" + }, + "createTask(address,bytes4,address,bytes)": { + "notice": "Create a task that tells Gelato to monitor and execute transactions on specific contracts" + }, + "createTaskNoPrepayment(address,bytes4,address,bytes,address)": { + "notice": "Create a task that tells Gelato to monitor and execute transactions on specific contracts" + }, + "createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)": { + "notice": "Create a timed task that executes every so often based on the inputted interval" + }, + "exec(uint256,address,address,bool,bool,bytes32,address,bytes)": { + "notice": "Execution API called by Gelato" + }, + "getFeeDetails()": { + "notice": "Helper func to query fee and feeToken" + }, + "getResolverHash(address,bytes)": { + "notice": "Helper func to query the resolverHash" + }, + "getSelector(string)": { + "notice": "Helper func to query the _selector of a function you want to automate" + }, + "getTaskId(address,address,bytes4,bool,address,bytes32)": { + "notice": "Returns TaskId of a task Creator" + }, + "getTaskIdsByUser(address)": { + "notice": "Helper func to query all open tasks by a task creator" + } + }, + "notice": "Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 1883, + "contract": "contracts/Ops.sol:Ops", + "label": "taskCreator", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes32,t_address)" + }, + { + "astId": 1887, + "contract": "contracts/Ops.sol:Ops", + "label": "execAddresses", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_address)" + }, + { + "astId": 1892, + "contract": "contracts/Ops.sol:Ops", + "label": "_createdTasks", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" + }, + { + "astId": 1897, + "contract": "contracts/Ops.sol:Ops", + "label": "fee", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 1899, + "contract": "contracts/Ops.sol:Ops", + "label": "feeToken", + "offset": 0, + "slot": "4", + "type": "t_address" + }, + { + "astId": 1904, + "contract": "contracts/Ops.sol:Ops", + "label": "timedTask", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.Bytes32Set)", + "numberOfBytes": "32", + "value": "t_struct(Bytes32Set)1433_storage" + }, + "t_mapping(t_bytes32,t_address)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct Ops.Time)", + "numberOfBytes": "32", + "value": "t_struct(Time)1876_storage" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(Bytes32Set)1433_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Bytes32Set", + "members": [ + { + "astId": 1432, + "contract": "contracts/Ops.sol:Ops", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/Ops.sol:Ops", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/Ops.sol:Ops", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Time)1876_storage": { + "encoding": "inplace", + "label": "struct Ops.Time", + "members": [ + { + "astId": 1873, + "contract": "contracts/Ops.sol:Ops", + "label": "nextExec", + "offset": 0, + "slot": "0", + "type": "t_uint128" + }, + { + "astId": 1875, + "contract": "contracts/Ops.sol:Ops", + "label": "interval", + "offset": 16, + "slot": "0", + "type": "t_uint128" + } + ], + "numberOfBytes": "32" + }, + "t_uint128": { + "encoding": "inplace", + "label": "uint128", + "numberOfBytes": "16" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/mumbai/Ops_Proxy.json b/deployments/mumbai/Ops_Proxy.json new file mode 100644 index 00000000..d126bc43 --- /dev/null +++ b/deployments/mumbai/Ops_Proxy.json @@ -0,0 +1,233 @@ +{ + "address": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "transactionIndex": 44, + "gasUsed": "641923", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000004000000400000000000000008000000000000000000000000000000000000000000000000000000000800401000000000000000100000000004000000000020000000000000000800800000000000000000080000000000000410000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000200000000000000000080000040000000004000000000000000000001000000000000000000000000000000100040000020000000000000001000000400000000000002000000000000010000000000100000", + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1", + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "logs": [ + { + "transactionIndex": 44, + "blockNumber": 25914256, + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "address": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000008ab6adbc1fec4f18617c9b889f5ce7f28401b8db" + ], + "data": "0x", + "logIndex": 150, + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1" + }, + { + "transactionIndex": 44, + "blockNumber": 25914256, + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "address": "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 151, + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1" + }, + { + "transactionIndex": 44, + "blockNumber": 25914256, + "transactionHash": "0x8dfd4dfcb181733b8812a81a507fc91425e55f841a96982f582a18d9547ae199", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000036bbd04a8a40600000000000000000000000000000000000000000000000006c002cd6191a1cf00000000000000000000000000000000000000000000106a81b472024c21634d00000000000000000000000000000000000000000000000006bc97105ce8fdc900000000000000000000000000000000000000000000106a81b7ddbf50ca0753", + "logIndex": 152, + "blockHash": "0xcaf01065fdff017befa6b0663c1605a5ea4d12eabf9237ed6a81ee13a83466b1" + } + ], + "blockNumber": 25914256, + "cumulativeGasUsed": "6689412", + "status": 1, + "byzantium": true + }, + "args": [ + "0x8aB6aDbC1fec4F18617C9B889F5cE7F28401B8dB", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0x" + ], + "numDeployments": 1, + "solcInputHash": "41a8600e180880fe88609322a6b2ac21", + "metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.8/proxy/EIP173Proxy.sol\":\"EIP173Proxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"solc_0.8/proxy/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setOwner(ownerAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function owner() external view returns (address) {\\n return _owner();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferOwnership(address newOwner) external onlyOwner {\\n _setOwner(newOwner);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyOwner {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyOwner() {\\n require(msg.sender == _owner(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _owner() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\\n }\\n }\\n\\n function _setOwner(address newOwner) internal {\\n address previousOwner = _owner();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\\n }\\n emit OwnershipTransferred(previousOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xb9c14a66c8a4eefabca13cc8dd8133c1587909bb1124fa793c50ab46358b63e4\",\"license\":\"MIT\"},\"solc_0.8/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data) internal {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\\n }\\n\\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x68c8cf1a340a53d31de8ed808bb66d64e83d50b20d80a0b2dff6aba903cebc98\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260405162000ccc38038062000ccc8339810160408190526200002691620001fc565b62000032838262000046565b6200003d8262000128565b505050620002fa565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8054908390556040516001600160a01b0380851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a381511562000123576000836001600160a01b031683604051620000ca9190620002dc565b600060405180830381855af49150503d806000811462000107576040519150601f19603f3d011682016040523d82523d6000602084013e6200010c565b606091505b505090508062000121573d806000803e806000fd5b505b505050565b60006200014260008051602062000cac8339815191525490565b90508160008051602062000cac83398151915255816001600160a01b0316816001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b80516001600160a01b0381168114620001b257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ea578181015183820152602001620001d0565b83811115620001215750506000910152565b6000806000606084860312156200021257600080fd5b6200021d846200019a565b92506200022d602085016200019a565b60408501519092506001600160401b03808211156200024b57600080fd5b818601915086601f8301126200026057600080fd5b815181811115620002755762000275620001b7565b604051601f8201601f19908116603f01168101908382118183101715620002a057620002a0620001b7565b81604052828152896020848701011115620002ba57600080fd5b620002cd836020830160208801620001cd565b80955050505050509250925092565b60008251620002f0818460208701620001cd565b9190910192915050565b6109a2806200030a6000396000f3fe60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101295780638da5cb5b1461013c578063f2fde38b14610176576100ca565b806301ffc9a7146100d45780633659cfe614610109576100ca565b366100ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a454354454400000000000000000000000000000000000060448201526064015b60405180910390fd5b6100d2610196565b005b3480156100e057600080fd5b506100f46100ef366004610806565b6101e1565b60405190151581526020015b60405180910390f35b34801561011557600080fd5b506100d2610124366004610871565b6103af565b6100d261013736600461088c565b610481565b34801561014857600080fd5b5061015161057c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b34801561018257600080fd5b506100d2610191366004610871565b6105ab565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156101d7578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061027457507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561028157506001919050565b7fffffffff0000000000000000000000000000000000000000000000000000000080831614156102b357506000919050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa92505050801561039b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526103989181019061090f565b60015b6103a85750600092915050565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e816040518060200160405280600081525061066a565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b6105778383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066a92505050565b505050565b60006105a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e81610759565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a38151156105775760008373ffffffffffffffffffffffffffffffffffffffff16836040516107059190610931565b600060405180830381855af49150503d8060008114610740576040519150601f19603f3d011682016040523d82523d6000602084013e610745565b606091505b50509050806101db573d806000803e806000fd5b60006107837fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020828403121561081857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146103a857600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461086c57600080fd5b919050565b60006020828403121561088357600080fd5b6103a882610848565b6000806000604084860312156108a157600080fd5b6108aa84610848565b9250602084013567ffffffffffffffff808211156108c757600080fd5b818601915086601f8301126108db57600080fd5b8135818111156108ea57600080fd5b8760208285010111156108fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561092157600080fd5b815180151581146103a857600080fd5b6000825160005b818110156109525760208186018101518583015201610938565b81811115610961576000828501525b50919091019291505056fea2646970667358221220d2ec357659da93a66b21590e3c56e508e51e4de5703da4d1f7ba0b98d9e047f964736f6c634300080a0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80634f1ef286116100435780634f1ef286146101295780638da5cb5b1461013c578063f2fde38b14610176576100ca565b806301ffc9a7146100d45780633659cfe614610109576100ca565b366100ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f45544845525f52454a454354454400000000000000000000000000000000000060448201526064015b60405180910390fd5b6100d2610196565b005b3480156100e057600080fd5b506100f46100ef366004610806565b6101e1565b60405190151581526020015b60405180910390f35b34801561011557600080fd5b506100d2610124366004610871565b6103af565b6100d261013736600461088c565b610481565b34801561014857600080fd5b5061015161057c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610100565b34801561018257600080fd5b506100d2610191366004610871565b6105ab565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460003681823780813683855af491503d8082833e8280156101d7578183f35b8183fd5b50505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061027457507f7f5828d0000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b1561028157506001919050565b7fffffffff0000000000000000000000000000000000000000000000000000000080831614156102b357506000919050565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fffffffff000000000000000000000000000000000000000000000000000000008416600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa92505050801561039b575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526103989181019061090f565b60015b6103a85750600092915050565b9392505050565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e816040518060200160405280600081525061066a565b50565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610537576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b6105778383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066a92505050565b505050565b60006105a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905090565b7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610661576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f4e4f545f415554484f52495a454400000000000000000000000000000000000060448201526064016100c1565b61047e81610759565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80549083905560405173ffffffffffffffffffffffffffffffffffffffff80851691908316907f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829690600090a38151156105775760008373ffffffffffffffffffffffffffffffffffffffff16836040516107059190610931565b600060405180830381855af49150503d8060008114610740576040519150601f19603f3d011682016040523d82523d6000602084013e610745565b606091505b50509050806101db573d806000803e806000fd5b60006107837fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020828403121561081857600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146103a857600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461086c57600080fd5b919050565b60006020828403121561088357600080fd5b6103a882610848565b6000806000604084860312156108a157600080fd5b6108aa84610848565b9250602084013567ffffffffffffffff808211156108c757600080fd5b818601915086601f8301126108db57600080fd5b8135818111156108ea57600080fd5b8760208285010111156108fc57600080fd5b6020830194508093505050509250925092565b60006020828403121561092157600080fd5b815180151581146103a857600080fd5b6000825160005b818110156109525760208186018101518583015201610938565b81811115610961576000828501525b50919091019291505056fea2646970667358221220d2ec357659da93a66b21590e3c56e508e51e4de5703da4d1f7ba0b98d9e047f964736f6c634300080a0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mumbai/TaskTreasuryL2.json b/deployments/mumbai/TaskTreasuryL2.json new file mode 100644 index 00000000..f3693420 --- /dev/null +++ b/deployments/mumbai/TaskTreasuryL2.json @@ -0,0 +1,598 @@ +{ + "address": "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb", + "abi": [ + { + "inputs": [ + { + "internalType": "address payable", + "name": "_gelato", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + } + ], + "name": "addWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "gelato", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + } + ], + "name": "removeWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "setMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x64cb34a72e8d4a566485ed6ec50a5bb6c92cbc06216ec08d0515e855c1263d8a", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb", + "transactionIndex": 9, + "gasUsed": "2341129", + "logsBloom": "0x00000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800001000000000000000100000000004000000000020000000000000000000800000000000000000080000000000000400000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000080000000000000004000800000000000000001000000000000000000000000000000100040000020000000000000000000000000000000000002000000000000010100000000100000", + "blockHash": "0x8d1a60d51c86fc0a52cf54d7964265a56d3ae2aebdd4fc1f3eae180769f24e2a", + "transactionHash": "0x64cb34a72e8d4a566485ed6ec50a5bb6c92cbc06216ec08d0515e855c1263d8a", + "logs": [ + { + "transactionIndex": 9, + "blockNumber": 25914192, + "transactionHash": "0x64cb34a72e8d4a566485ed6ec50a5bb6c92cbc06216ec08d0515e855c1263d8a", + "address": "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 32, + "blockHash": "0x8d1a60d51c86fc0a52cf54d7964265a56d3ae2aebdd4fc1f3eae180769f24e2a" + }, + { + "transactionIndex": 9, + "blockNumber": 25914192, + "transactionHash": "0x64cb34a72e8d4a566485ed6ec50a5bb6c92cbc06216ec08d0515e855c1263d8a", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x000000000000000000000000000000000000000000000000000c79dddbe8191200000000000000000000000000000000000000000000000006f05b59d3b2000000000000000000000000000000000000000000000000106a30168ee0b76f6fee00000000000000000000000000000000000000000000000006e3e17bf7c9e6ee00000000000000000000000000000000000000000000106a302308be93578900", + "logIndex": 33, + "blockHash": "0x8d1a60d51c86fc0a52cf54d7964265a56d3ae2aebdd4fc1f3eae180769f24e2a" + } + ], + "blockNumber": 25914192, + "cumulativeGasUsed": "3572451", + "status": 1, + "byzantium": true + }, + "args": [ + "0x25aD59adbe00C2d80c86d01e2E05e1294DA84823", + "10000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"}],\"name\":\"addWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gelato\",\"outputs\":[{\"internalType\":\"address payable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"}],\"name\":\"removeWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"setMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"addWhitelistedService(address)\":{\"params\":{\"_service\":\"New service to add\"}},\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"removeWhitelistedService(address)\":{\"params\":{\"_service\":\"Old service to remove\"}},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"setMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"useFunds(address,uint256,address)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addWhitelistedService(address)\":{\"notice\":\"Add new service that can call useFunds. Gelato Governance\"},\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user\"},\"removeWhitelistedService(address)\":{\"notice\":\"Remove old service that can call useFunds. Gelato Governance\"},\"setMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"useFunds(address,uint256,address)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Ops\\\"\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryL2.sol\":\"TaskTreasuryL2\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x24e0364e503a9bbde94c715d26573a76f14cd2a202d45f96f52134ab806b67b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x0e9621f60b2faabe65549f7ed0f24e8853a45c1b7990d47e8160e523683f3935\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0xc995bddbca1ae19788db9f8b61e63385edd3fddf89693b612d5abd1a275974d2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/taskTreasury/TaskTreasuryL2.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\n\\n// solhint-disable max-states-count\\n// solhint-disable max-line-length\\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n uint256 public maxFee;\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato, uint256 _maxFee) {\\n gelato = _gelato;\\n maxFee = _maxFee;\\n }\\n\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: useFunds: Overchared\\\");\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\\n maxFee = _newMaxFee;\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x452ef503706fa14abc4026326690d3b4cdbd478e9c73ee74e4b5b50a57550647\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162002aa338038062002aa3833981810160405281019062000037919062000212565b620000576200004b620000a160201b60201c565b620000a960201b60201c565b600180819055508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505080600281905550505062000259565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019f8262000172565b9050919050565b620001b18162000192565b8114620001bd57600080fd5b50565b600081519050620001d181620001a6565b92915050565b6000819050919050565b620001ec81620001d7565b8114620001f857600080fd5b50565b6000815190506200020c81620001e1565b92915050565b600080604083850312156200022c576200022b6200016d565b5b60006200023c85828601620001c0565b92505060206200024f85828601620001fb565b9150509250929050565b6080516128276200027c600039600081816106f30152610a8201526128276000f3fe6080604052600436106100dd5760003560e01c8063715018a61161007f578063b47064c811610059578063b47064c814610286578063c1461d57146102c3578063c63aa029146102df578063f2fde38b14610308576100dd565b8063715018a61461021b578063848f5f3d146102325780638da5cb5b1461025b576100dd565b8063573ea575116100bb578063573ea575146101735780635dfad06a1461019e5780636f192acc146101c9578063710e5d2f146101f2576100dd565b806301f59d16146100e25780631c20fadd1461010d5780632bf30a0e14610136575b600080fd5b3480156100ee57600080fd5b506100f7610331565b6040516101049190611aaa565b60405180910390f35b34801561011957600080fd5b50610134600480360381019061012f9190611b92565b610337565b005b34801561014257600080fd5b5061015d60048036038101906101589190611be5565b610590565b60405161016a9190611cd0565b60405180910390f35b34801561017f57600080fd5b506101886106f1565b6040516101959190611d01565b60405180910390f35b3480156101aa57600080fd5b506101b3610715565b6040516101c09190611cd0565b60405180910390f35b3480156101d557600080fd5b506101f060048036038101906101eb9190611d1c565b6107fa565b005b3480156101fe57600080fd5b5061021960048036038101906102149190611d6f565b610aad565b005b34801561022757600080fd5b50610230610b33565b005b34801561023e57600080fd5b5061025960048036038101906102549190611be5565b610bbb565b005b34801561026757600080fd5b50610270610ca2565b60405161027d9190611dab565b60405180910390f35b34801561029257600080fd5b506102ad60048036038101906102a89190611dc6565b610ccb565b6040516102ba9190611aaa565b60405180910390f35b6102dd60048036038101906102d89190611e06565b610cf0565b005b3480156102eb57600080fd5b5061030660048036038101906103019190611be5565b611093565b005b34801561031457600080fd5b5061032f600480360381019061032a9190611be5565b61117b565b005b60025481565b6002600154141561037d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037490611eb6565b60405180910390fd5b60026001819055506000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006104128284611273565b905080826104209190611f05565b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506104ab85858361128c565b818114156105065761050484600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061139790919063ffffffff16565b505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff38460405161057a9190611aaa565b60405180910390a4505060018081905550505050565b606060006105db600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113c7565b905060008167ffffffffffffffff8111156105f9576105f8611f39565b5b6040519080825280602002602001820160405280156106275781602001602082028036833780820191505090505b50905060005b828110156106e65761068681600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113dc90919063ffffffff16565b82828151811061069957610698611f68565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806106de90611f97565b91505061062d565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6060600061072360056113c7565b905060008167ffffffffffffffff81111561074157610740611f39565b5b60405190808252806020026020018201604052801561076f5781602001602082028036833780820191505090505b50905060005b828110156107f1576107918160056113dc90919063ffffffff16565b8282815181106107a4576107a3611f68565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806107e990611f97565b915050610775565b50809250505090565b61080e3360056113f690919063ffffffff16565b61084d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084490612052565b60405180910390fd5b60006002541461089d5781600254101561089c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610893906120e4565b60405180910390fd5b5b81600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546109259190611f05565b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610a7d57610a7b83600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061139790919063ffffffff16565b505b610aa87f0000000000000000000000000000000000000000000000000000000000000000848461128c565b505050565b610ab5611426565b73ffffffffffffffffffffffffffffffffffffffff16610ad3610ca2565b73ffffffffffffffffffffffffffffffffffffffff1614610b29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2090612150565b60405180910390fd5b8060028190555050565b610b3b611426565b73ffffffffffffffffffffffffffffffffffffffff16610b59610ca2565b73ffffffffffffffffffffffffffffffffffffffff1614610baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba690612150565b60405180910390fd5b610bb9600061142e565b565b610bc3611426565b73ffffffffffffffffffffffffffffffffffffffff16610be1610ca2565b73ffffffffffffffffffffffffffffffffffffffff1614610c37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2e90612150565b60405180910390fd5b610c4b8160056113f690919063ffffffff16565b610c8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c81906121e2565b60405180910390fd5b610c9e81600561139790919063ffffffff16565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6003602052816000526040600020602052806000526040600020600091509150505481565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610d4257349050610e82565b600083905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610d829190611dab565b602060405180830381865afa158015610d9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc39190612217565b9050610df23330868573ffffffffffffffffffffffffffffffffffffffff166114f2909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610e2d9190611dab565b602060405180830381865afa158015610e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e9190612217565b90508181610e7c9190611f05565b93505050505b80600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f0a9190612244565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610fdb83600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113f690919063ffffffff16565b6110325761103083600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061157b90919063ffffffff16565b505b808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a450505050565b61109b611426565b73ffffffffffffffffffffffffffffffffffffffff166110b9610ca2565b73ffffffffffffffffffffffffffffffffffffffff161461110f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110690612150565b60405180910390fd5b6111238160056113f690919063ffffffff16565b15611163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115a9061230c565b60405180910390fd5b61117781600561157b90919063ffffffff16565b5050565b611183611426565b73ffffffffffffffffffffffffffffffffffffffff166111a1610ca2565b73ffffffffffffffffffffffffffffffffffffffff16146111f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ee90612150565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125e9061239e565b60405180910390fd5b6112708161142e565b50565b60008183106112825781611284565b825b905092915050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156113865760008373ffffffffffffffffffffffffffffffffffffffff16826040516112fa906123ef565b60006040518083038185875af1925050503d8060008114611337576040519150601f19603f3d011682016040523d82523d6000602084013e61133c565b606091505b5050905080611380576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137790612450565b60405180910390fd5b50611392565b6113918284836115ab565b5b505050565b60006113bf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611631565b905092915050565b60006113d582600001611745565b9050919050565b60006113eb8360000183611756565b60001c905092915050565b600061141e836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611781565b905092915050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611575846323b872dd60e01b85858560405160240161151393929190612470565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a4565b50505050565b60006115a3836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61186b565b905092915050565b61162c8363a9059cbb60e01b84846040516024016115ca9291906124a7565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a4565b505050565b600080836001016000848152602001908152602001600020549050600081146117395760006001826116639190611f05565b905060006001866000018054905061167b9190611f05565b90508181146116ea57600086600001828154811061169c5761169b611f68565b5b90600052602060002001549050808760000184815481106116c0576116bf611f68565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806116fe576116fd6124d0565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061173f565b60009150505b92915050565b600081600001805490509050919050565b600082600001828154811061176e5761176d611f68565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166118db9092919063ffffffff16565b905060008151111561186657808060200190518101906118269190612537565b611865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185c906125d6565b60405180910390fd5b5b505050565b60006118778383611781565b6118d05782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506118d5565b600090505b92915050565b60606118ea84846000856118f3565b90509392505050565b606082471015611938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192f90612668565b60405180910390fd5b61194185611a07565b611980576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611977906126d4565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516119a99190612763565b60006040518083038185875af1925050503d80600081146119e6576040519150601f19603f3d011682016040523d82523d6000602084013e6119eb565b606091505b50915091506119fb828286611a2a565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315611a3a57829050611a8a565b600083511115611a4d5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8191906127cf565b60405180910390fd5b9392505050565b6000819050919050565b611aa481611a91565b82525050565b6000602082019050611abf6000830184611a9b565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611af582611aca565b9050919050565b611b0581611aea565b8114611b1057600080fd5b50565b600081359050611b2281611afc565b92915050565b6000611b3382611aca565b9050919050565b611b4381611b28565b8114611b4e57600080fd5b50565b600081359050611b6081611b3a565b92915050565b611b6f81611a91565b8114611b7a57600080fd5b50565b600081359050611b8c81611b66565b92915050565b600080600060608486031215611bab57611baa611ac5565b5b6000611bb986828701611b13565b9350506020611bca86828701611b51565b9250506040611bdb86828701611b7d565b9150509250925092565b600060208284031215611bfb57611bfa611ac5565b5b6000611c0984828501611b51565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611c4781611b28565b82525050565b6000611c598383611c3e565b60208301905092915050565b6000602082019050919050565b6000611c7d82611c12565b611c878185611c1d565b9350611c9283611c2e565b8060005b83811015611cc3578151611caa8882611c4d565b9750611cb583611c65565b925050600181019050611c96565b5085935050505092915050565b60006020820190508181036000830152611cea8184611c72565b905092915050565b611cfb81611aea565b82525050565b6000602082019050611d166000830184611cf2565b92915050565b600080600060608486031215611d3557611d34611ac5565b5b6000611d4386828701611b51565b9350506020611d5486828701611b7d565b9250506040611d6586828701611b51565b9150509250925092565b600060208284031215611d8557611d84611ac5565b5b6000611d9384828501611b7d565b91505092915050565b611da581611b28565b82525050565b6000602082019050611dc06000830184611d9c565b92915050565b60008060408385031215611ddd57611ddc611ac5565b5b6000611deb85828601611b51565b9250506020611dfc85828601611b51565b9150509250929050565b600080600060608486031215611e1f57611e1e611ac5565b5b6000611e2d86828701611b51565b9350506020611e3e86828701611b51565b9250506040611e4f86828701611b7d565b9150509250925092565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000611ea0601f83611e59565b9150611eab82611e6a565b602082019050919050565b60006020820190508181036000830152611ecf81611e93565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611f1082611a91565b9150611f1b83611a91565b925082821015611f2e57611f2d611ed6565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000611fa282611a91565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611fd557611fd4611ed6565b5b600182019050919050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b600061203c602583611e59565b915061204782611fe0565b604082019050919050565b6000602082019050818103600083015261206b8161202f565b9050919050565b7f5461736b54726561737572793a2075736546756e64733a204f7665726368617260008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b60006120ce602283611e59565b91506120d982612072565b604082019050919050565b600060208201905081810360008301526120fd816120c1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061213a602083611e59565b915061214582612104565b602082019050919050565b600060208201905081810360008301526121698161212d565b9050919050565b7f5461736b54726561737572793a2061646457686974656c69737465645365727660008201527f6963653a202177686974656c6973746564000000000000000000000000000000602082015250565b60006121cc603183611e59565b91506121d782612170565b604082019050919050565b600060208201905081810360008301526121fb816121bf565b9050919050565b60008151905061221181611b66565b92915050565b60006020828403121561222d5761222c611ac5565b5b600061223b84828501612202565b91505092915050565b600061224f82611a91565b915061225a83611a91565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561228f5761228e611ed6565b5b828201905092915050565b7f5461736b54726561737572793a2061646457686974656c69737465645365727660008201527f6963653a2077686974656c697374656400000000000000000000000000000000602082015250565b60006122f6603083611e59565b91506123018261229a565b604082019050919050565b60006020820190508181036000830152612325816122e9565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612388602683611e59565b91506123938261232c565b604082019050919050565b600060208201905081810360008301526123b78161237b565b9050919050565b600081905092915050565b50565b60006123d96000836123be565b91506123e4826123c9565b600082019050919050565b60006123fa826123cc565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b600061243a601e83611e59565b915061244582612404565b602082019050919050565b600060208201905081810360008301526124698161242d565b9050919050565b60006060820190506124856000830186611d9c565b6124926020830185611d9c565b61249f6040830184611a9b565b949350505050565b60006040820190506124bc6000830185611d9c565b6124c96020830184611a9b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008115159050919050565b612514816124ff565b811461251f57600080fd5b50565b6000815190506125318161250b565b92915050565b60006020828403121561254d5761254c611ac5565b5b600061255b84828501612522565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006125c0602a83611e59565b91506125cb82612564565b604082019050919050565b600060208201905081810360008301526125ef816125b3565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000612652602683611e59565b915061265d826125f6565b604082019050919050565b6000602082019050818103600083015261268181612645565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006126be601d83611e59565b91506126c982612688565b602082019050919050565b600060208201905081810360008301526126ed816126b1565b9050919050565b600081519050919050565b60005b8381101561271d578082015181840152602081019050612702565b8381111561272c576000848401525b50505050565b600061273d826126f4565b61274781856123be565b93506127578185602086016126ff565b80840191505092915050565b600061276f8284612732565b915081905092915050565b600081519050919050565b6000601f19601f8301169050919050565b60006127a18261277a565b6127ab8185611e59565b93506127bb8185602086016126ff565b6127c481612785565b840191505092915050565b600060208201905081810360008301526127e98184612796565b90509291505056fea2646970667358221220e43388a58ec477738b20fba948d59aa00d4dd155d1c7f5703b2a260e2e2410fa64736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100dd5760003560e01c8063715018a61161007f578063b47064c811610059578063b47064c814610286578063c1461d57146102c3578063c63aa029146102df578063f2fde38b14610308576100dd565b8063715018a61461021b578063848f5f3d146102325780638da5cb5b1461025b576100dd565b8063573ea575116100bb578063573ea575146101735780635dfad06a1461019e5780636f192acc146101c9578063710e5d2f146101f2576100dd565b806301f59d16146100e25780631c20fadd1461010d5780632bf30a0e14610136575b600080fd5b3480156100ee57600080fd5b506100f7610331565b6040516101049190611aaa565b60405180910390f35b34801561011957600080fd5b50610134600480360381019061012f9190611b92565b610337565b005b34801561014257600080fd5b5061015d60048036038101906101589190611be5565b610590565b60405161016a9190611cd0565b60405180910390f35b34801561017f57600080fd5b506101886106f1565b6040516101959190611d01565b60405180910390f35b3480156101aa57600080fd5b506101b3610715565b6040516101c09190611cd0565b60405180910390f35b3480156101d557600080fd5b506101f060048036038101906101eb9190611d1c565b6107fa565b005b3480156101fe57600080fd5b5061021960048036038101906102149190611d6f565b610aad565b005b34801561022757600080fd5b50610230610b33565b005b34801561023e57600080fd5b5061025960048036038101906102549190611be5565b610bbb565b005b34801561026757600080fd5b50610270610ca2565b60405161027d9190611dab565b60405180910390f35b34801561029257600080fd5b506102ad60048036038101906102a89190611dc6565b610ccb565b6040516102ba9190611aaa565b60405180910390f35b6102dd60048036038101906102d89190611e06565b610cf0565b005b3480156102eb57600080fd5b5061030660048036038101906103019190611be5565b611093565b005b34801561031457600080fd5b5061032f600480360381019061032a9190611be5565b61117b565b005b60025481565b6002600154141561037d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037490611eb6565b60405180910390fd5b60026001819055506000600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006104128284611273565b905080826104209190611f05565b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506104ab85858361128c565b818114156105065761050484600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061139790919063ffffffff16565b505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff38460405161057a9190611aaa565b60405180910390a4505060018081905550505050565b606060006105db600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113c7565b905060008167ffffffffffffffff8111156105f9576105f8611f39565b5b6040519080825280602002602001820160405280156106275781602001602082028036833780820191505090505b50905060005b828110156106e65761068681600460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113dc90919063ffffffff16565b82828151811061069957610698611f68565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806106de90611f97565b91505061062d565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6060600061072360056113c7565b905060008167ffffffffffffffff81111561074157610740611f39565b5b60405190808252806020026020018201604052801561076f5781602001602082028036833780820191505090505b50905060005b828110156107f1576107918160056113dc90919063ffffffff16565b8282815181106107a4576107a3611f68565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505080806107e990611f97565b915050610775565b50809250505090565b61080e3360056113f690919063ffffffff16565b61084d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161084490612052565b60405180910390fd5b60006002541461089d5781600254101561089c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610893906120e4565b60405180910390fd5b5b81600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546109259190611f05565b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541415610a7d57610a7b83600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061139790919063ffffffff16565b505b610aa87f0000000000000000000000000000000000000000000000000000000000000000848461128c565b505050565b610ab5611426565b73ffffffffffffffffffffffffffffffffffffffff16610ad3610ca2565b73ffffffffffffffffffffffffffffffffffffffff1614610b29576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2090612150565b60405180910390fd5b8060028190555050565b610b3b611426565b73ffffffffffffffffffffffffffffffffffffffff16610b59610ca2565b73ffffffffffffffffffffffffffffffffffffffff1614610baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba690612150565b60405180910390fd5b610bb9600061142e565b565b610bc3611426565b73ffffffffffffffffffffffffffffffffffffffff16610be1610ca2565b73ffffffffffffffffffffffffffffffffffffffff1614610c37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2e90612150565b60405180910390fd5b610c4b8160056113f690919063ffffffff16565b610c8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c81906121e2565b60405180910390fd5b610c9e81600561139790919063ffffffff16565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6003602052816000526040600020602052806000526040600020600091509150505481565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610d4257349050610e82565b600083905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610d829190611dab565b602060405180830381865afa158015610d9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc39190612217565b9050610df23330868573ffffffffffffffffffffffffffffffffffffffff166114f2909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610e2d9190611dab565b602060405180830381865afa158015610e4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6e9190612217565b90508181610e7c9190611f05565b93505050505b80600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f0a9190612244565b600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610fdb83600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206113f690919063ffffffff16565b6110325761103083600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061157b90919063ffffffff16565b505b808373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a450505050565b61109b611426565b73ffffffffffffffffffffffffffffffffffffffff166110b9610ca2565b73ffffffffffffffffffffffffffffffffffffffff161461110f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110690612150565b60405180910390fd5b6111238160056113f690919063ffffffff16565b15611163576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161115a9061230c565b60405180910390fd5b61117781600561157b90919063ffffffff16565b5050565b611183611426565b73ffffffffffffffffffffffffffffffffffffffff166111a1610ca2565b73ffffffffffffffffffffffffffffffffffffffff16146111f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ee90612150565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125e9061239e565b60405180910390fd5b6112708161142e565b50565b60008183106112825781611284565b825b905092915050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156113865760008373ffffffffffffffffffffffffffffffffffffffff16826040516112fa906123ef565b60006040518083038185875af1925050503d8060008114611337576040519150601f19603f3d011682016040523d82523d6000602084013e61133c565b606091505b5050905080611380576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137790612450565b60405180910390fd5b50611392565b6113918284836115ab565b5b505050565b60006113bf836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611631565b905092915050565b60006113d582600001611745565b9050919050565b60006113eb8360000183611756565b60001c905092915050565b600061141e836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611781565b905092915050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611575846323b872dd60e01b85858560405160240161151393929190612470565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a4565b50505050565b60006115a3836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61186b565b905092915050565b61162c8363a9059cbb60e01b84846040516024016115ca9291906124a7565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506117a4565b505050565b600080836001016000848152602001908152602001600020549050600081146117395760006001826116639190611f05565b905060006001866000018054905061167b9190611f05565b90508181146116ea57600086600001828154811061169c5761169b611f68565b5b90600052602060002001549050808760000184815481106116c0576116bf611f68565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806116fe576116fd6124d0565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061173f565b60009150505b92915050565b600081600001805490509050919050565b600082600001828154811061176e5761176d611f68565b5b9060005260206000200154905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166118db9092919063ffffffff16565b905060008151111561186657808060200190518101906118269190612537565b611865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161185c906125d6565b60405180910390fd5b5b505050565b60006118778383611781565b6118d05782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506118d5565b600090505b92915050565b60606118ea84846000856118f3565b90509392505050565b606082471015611938576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192f90612668565b60405180910390fd5b61194185611a07565b611980576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611977906126d4565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516119a99190612763565b60006040518083038185875af1925050503d80600081146119e6576040519150601f19603f3d011682016040523d82523d6000602084013e6119eb565b606091505b50915091506119fb828286611a2a565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315611a3a57829050611a8a565b600083511115611a4d5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8191906127cf565b60405180910390fd5b9392505050565b6000819050919050565b611aa481611a91565b82525050565b6000602082019050611abf6000830184611a9b565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611af582611aca565b9050919050565b611b0581611aea565b8114611b1057600080fd5b50565b600081359050611b2281611afc565b92915050565b6000611b3382611aca565b9050919050565b611b4381611b28565b8114611b4e57600080fd5b50565b600081359050611b6081611b3a565b92915050565b611b6f81611a91565b8114611b7a57600080fd5b50565b600081359050611b8c81611b66565b92915050565b600080600060608486031215611bab57611baa611ac5565b5b6000611bb986828701611b13565b9350506020611bca86828701611b51565b9250506040611bdb86828701611b7d565b9150509250925092565b600060208284031215611bfb57611bfa611ac5565b5b6000611c0984828501611b51565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b611c4781611b28565b82525050565b6000611c598383611c3e565b60208301905092915050565b6000602082019050919050565b6000611c7d82611c12565b611c878185611c1d565b9350611c9283611c2e565b8060005b83811015611cc3578151611caa8882611c4d565b9750611cb583611c65565b925050600181019050611c96565b5085935050505092915050565b60006020820190508181036000830152611cea8184611c72565b905092915050565b611cfb81611aea565b82525050565b6000602082019050611d166000830184611cf2565b92915050565b600080600060608486031215611d3557611d34611ac5565b5b6000611d4386828701611b51565b9350506020611d5486828701611b7d565b9250506040611d6586828701611b51565b9150509250925092565b600060208284031215611d8557611d84611ac5565b5b6000611d9384828501611b7d565b91505092915050565b611da581611b28565b82525050565b6000602082019050611dc06000830184611d9c565b92915050565b60008060408385031215611ddd57611ddc611ac5565b5b6000611deb85828601611b51565b9250506020611dfc85828601611b51565b9150509250929050565b600080600060608486031215611e1f57611e1e611ac5565b5b6000611e2d86828701611b51565b9350506020611e3e86828701611b51565b9250506040611e4f86828701611b7d565b9150509250925092565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000611ea0601f83611e59565b9150611eab82611e6a565b602082019050919050565b60006020820190508181036000830152611ecf81611e93565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611f1082611a91565b9150611f1b83611a91565b925082821015611f2e57611f2d611ed6565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000611fa282611a91565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611fd557611fd4611ed6565b5b600182019050919050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b600061203c602583611e59565b915061204782611fe0565b604082019050919050565b6000602082019050818103600083015261206b8161202f565b9050919050565b7f5461736b54726561737572793a2075736546756e64733a204f7665726368617260008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b60006120ce602283611e59565b91506120d982612072565b604082019050919050565b600060208201905081810360008301526120fd816120c1565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061213a602083611e59565b915061214582612104565b602082019050919050565b600060208201905081810360008301526121698161212d565b9050919050565b7f5461736b54726561737572793a2061646457686974656c69737465645365727660008201527f6963653a202177686974656c6973746564000000000000000000000000000000602082015250565b60006121cc603183611e59565b91506121d782612170565b604082019050919050565b600060208201905081810360008301526121fb816121bf565b9050919050565b60008151905061221181611b66565b92915050565b60006020828403121561222d5761222c611ac5565b5b600061223b84828501612202565b91505092915050565b600061224f82611a91565b915061225a83611a91565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561228f5761228e611ed6565b5b828201905092915050565b7f5461736b54726561737572793a2061646457686974656c69737465645365727660008201527f6963653a2077686974656c697374656400000000000000000000000000000000602082015250565b60006122f6603083611e59565b91506123018261229a565b604082019050919050565b60006020820190508181036000830152612325816122e9565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612388602683611e59565b91506123938261232c565b604082019050919050565b600060208201905081810360008301526123b78161237b565b9050919050565b600081905092915050565b50565b60006123d96000836123be565b91506123e4826123c9565b600082019050919050565b60006123fa826123cc565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b600061243a601e83611e59565b915061244582612404565b602082019050919050565b600060208201905081810360008301526124698161242d565b9050919050565b60006060820190506124856000830186611d9c565b6124926020830185611d9c565b61249f6040830184611a9b565b949350505050565b60006040820190506124bc6000830185611d9c565b6124c96020830184611a9b565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008115159050919050565b612514816124ff565b811461251f57600080fd5b50565b6000815190506125318161250b565b92915050565b60006020828403121561254d5761254c611ac5565b5b600061255b84828501612522565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b60006125c0602a83611e59565b91506125cb82612564565b604082019050919050565b600060208201905081810360008301526125ef816125b3565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000612652602683611e59565b915061265d826125f6565b604082019050919050565b6000602082019050818103600083015261268181612645565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006126be601d83611e59565b91506126c982612688565b602082019050919050565b600060208201905081810360008301526126ed816126b1565b9050919050565b600081519050919050565b60005b8381101561271d578082015181840152602081019050612702565b8381111561272c576000848401525b50505050565b600061273d826126f4565b61274781856123be565b93506127578185602086016126ff565b80840191505092915050565b600061276f8284612732565b915081905092915050565b600081519050919050565b6000601f19601f8301169050919050565b60006127a18261277a565b6127ab8185611e59565b93506127bb8185602086016126ff565b6127c481612785565b840191505092915050565b600060208201905081810360008301526127e98184612796565b90509291505056fea2646970667358221220e43388a58ec477738b20fba948d59aa00d4dd155d1c7f5703b2a260e2e2410fa64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "addWhitelistedService(address)": { + "params": { + "_service": "New service to add" + } + }, + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "removeWhitelistedService(address)": { + "params": { + "_service": "Old service to remove" + } + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "setMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "useFunds(address,uint256,address)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "addWhitelistedService(address)": { + "notice": "Add new service that can call useFunds. Gelato Governance" + }, + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user" + }, + "removeWhitelistedService(address)": { + "notice": "Remove old service that can call useFunds. Gelato Governance" + }, + "setMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "useFunds(address,uint256,address)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Ops\"" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 384, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 492, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 3941, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "maxFee", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 3947, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "userTokenBalance", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 3952, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_tokenCredits", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 3955, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_whitelistedServices", + "offset": 0, + "slot": "5", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryL2.sol:TaskTreasuryL2", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/mumbai/TaskTreasuryUpgradable.json b/deployments/mumbai/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..a1020fb6 --- /dev/null +++ b/deployments/mumbai/TaskTreasuryUpgradable.json @@ -0,0 +1,662 @@ +{ + "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "transactionIndex": 22, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000800000000000000400000000000000000000000000000000400000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000020000000000000000000800000000000000000080000000000000000000080008000000000000000000000000000000000080000000000000000000200000000000000000000000000200000000000000000080000000000000004000000000000008000001000000000010000000000000000000100040000020000000000000000000000400000000000002000800000000010000000000100000", + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9", + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "logs": [ + { + "transactionIndex": 22, + "blockNumber": 25914236, + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000095f4538c3950ce0ef5821f2049ae2ac5ccade68d" + ], + "data": "0x", + "logIndex": 78, + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9" + }, + { + "transactionIndex": 22, + "blockNumber": 25914236, + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 79, + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9" + }, + { + "transactionIndex": 22, + "blockNumber": 25914236, + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x000000000000000000000000000000000000000000000000000410c872100a0000000000000000000000000000000000000000000000000006d252b2bb3af3e100000000000000000000000000000000000000000000106a5fabb6d410a1bfe300000000000000000000000000000000000000000000000006ce41ea492ae9e100000000000000000000000000000000000000000000106a5fafc79c82b1c9e3", + "logIndex": 80, + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9" + } + ], + "blockNumber": 25914236, + "cumulativeGasUsed": "4046108", + "status": 1, + "byzantium": true + }, + "args": [ + "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x00" + } + ] + }, + "implementation": "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mumbai/TaskTreasuryUpgradable_Implementation.json b/deployments/mumbai/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..881bdbb8 --- /dev/null +++ b/deployments/mumbai/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,765 @@ +{ + "address": "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb55b0e0eb133a83a3505662dbb54b540409732e6a0d1bbde0d4b4638baec4729", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D", + "transactionIndex": 19, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000080000000000000000000200000000000000000000000000000000000000000000080000000000000004000000000000000000001000000000000000000000000000000100040000000000000000000000000000000000000000002000000000000010000000000100000", + "blockHash": "0xf35be581d35cc9f87f4bba0ae7ce2aa8f7e48b9d5770e6f65513c8332980fb26", + "transactionHash": "0xb55b0e0eb133a83a3505662dbb54b540409732e6a0d1bbde0d4b4638baec4729", + "logs": [ + { + "transactionIndex": 19, + "blockNumber": 25914234, + "transactionHash": "0xb55b0e0eb133a83a3505662dbb54b540409732e6a0d1bbde0d4b4638baec4729", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x00000000000000000000000000000000000000000000000000118ec93900b70000000000000000000000000000000000000000000000000006e3e17bf664ac9400000000000000000000000000000000000000000000106a5e8465cd9074df4500000000000000000000000000000000000000000000000006d252b2bd63f59400000000000000000000000000000000000000000000106a5e95f496c9759645", + "logIndex": 124, + "blockHash": "0xf35be581d35cc9f87f4bba0ae7ce2aa8f7e48b9d5770e6f65513c8332980fb26" + } + ], + "blockNumber": 25914234, + "cumulativeGasUsed": "5818165", + "status": 1, + "byzantium": true + }, + "args": ["0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb"], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/mumbai/TaskTreasuryUpgradable_Proxy.json b/deployments/mumbai/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..d855d598 --- /dev/null +++ b/deployments/mumbai/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,233 @@ +{ + "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "transactionIndex": 22, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000800000000000000400000000000000000000000000000000400000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000004000000000020000000000000000000800000000000000000080000000000000000000080008000000000000000000000000000000000080000000000000000000200000000000000000000000000200000000000000000080000000000000004000000000000008000001000000000010000000000000000000100040000020000000000000000000000400000000000002000800000000010000000000100000", + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9", + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "logs": [ + { + "transactionIndex": 22, + "blockNumber": 25914236, + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000095f4538c3950ce0ef5821f2049ae2ac5ccade68d" + ], + "data": "0x", + "logIndex": 78, + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9" + }, + { + "transactionIndex": 22, + "blockNumber": 25914236, + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "address": "0x527a819db1eb0e34426297b03bae11F2f8B3A19E", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 79, + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9" + }, + { + "transactionIndex": 22, + "blockNumber": 25914236, + "transactionHash": "0x2b07c46f6e92cc6475d7581d0469dd19ec31c6602ae98ef2e2382b3d07234666", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0", + "0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f" + ], + "data": "0x000000000000000000000000000000000000000000000000000410c872100a0000000000000000000000000000000000000000000000000006d252b2bb3af3e100000000000000000000000000000000000000000000106a5fabb6d410a1bfe300000000000000000000000000000000000000000000000006ce41ea492ae9e100000000000000000000000000000000000000000000106a5fafc79c82b1c9e3", + "logIndex": 80, + "blockHash": "0x72d56006cad112262317d53d1f25617733d2f71d9b0f11451e0ffcc360f8fea9" + } + ], + "blockNumber": 25914236, + "cumulativeGasUsed": "4046108", + "status": 1, + "byzantium": true + }, + "args": [ + "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/mumbai/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/mumbai/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/mumbai/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/mumbai/solcInputs/41a8600e180880fe88609322a6b2ac21.json b/deployments/mumbai/solcInputs/41a8600e180880fe88609322a6b2ac21.json new file mode 100644 index 00000000..55724182 --- /dev/null +++ b/deployments/mumbai/solcInputs/41a8600e180880fe88609322a6b2ac21.json @@ -0,0 +1,39 @@ +{ + "language": "Solidity", + "sources": { + "solc_0.8/proxy/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setOwner(ownerAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function owner() external view returns (address) {\n return _owner();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferOwnership(address newOwner) external onlyOwner {\n _setOwner(newOwner);\n }\n\n function upgradeTo(address newImplementation) external onlyOwner {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyOwner() {\n require(msg.sender == _owner(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _owner() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103)\n }\n }\n\n function _setOwner(address newOwner) internal {\n address previousOwner = _owner();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner)\n }\n emit OwnershipTransferred(previousOwner, newOwner);\n }\n}\n" + }, + "solc_0.8/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation);\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0)\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data) internal {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation)\n }\n\n emit ProxyImplementationUpdated(previousImplementation, newImplementation);\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "solc_0.8/proxy/EIP173ProxyWithReceive.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 999999 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/rinkeby/Ops.json b/deployments/rinkeby/Ops.json index 74a05460..5c0b89d3 100644 --- a/deployments/rinkeby/Ops.json +++ b/deployments/rinkeby/Ops.json @@ -3637,7 +3637,7 @@ } } ], - "implementation": "0x028AB145e107CF37a64467ef0BddAD30e768Fa07", + "implementation": "0xf723308cE272f067Bc35d2129aceF13beDEB3F2C", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/rinkeby/Ops_Implementation.json b/deployments/rinkeby/Ops_Implementation.json index c41f6aff..ab084ac2 100644 --- a/deployments/rinkeby/Ops_Implementation.json +++ b/deployments/rinkeby/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x028AB145e107CF37a64467ef0BddAD30e768Fa07", + "address": "0xf723308cE272f067Bc35d2129aceF13beDEB3F2C", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0xdc643ffbb8e5a5bfa3362dfb0c6757ec2b944cd1d2ceb528274772bfa8e7cc1c", + "transactionHash": "0x5f9a808c50fb271ca8c8b605da5ee836dd814c4cf9d3ccaaea357933c2d6ae5a", "receipt": { "to": null, - "from": "0xAabB54394E8dd61Dd70897E9c80be8de7C64A895", - "contractAddress": "0x028AB145e107CF37a64467ef0BddAD30e768Fa07", - "transactionIndex": 1, - "gasUsed": "2650216", + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xf723308cE272f067Bc35d2129aceF13beDEB3F2C", + "transactionIndex": 36, + "gasUsed": "2673374", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x200406ebc69bac20c3abaa9e189288e6a14acc1bfbd147ed0ead6bdea4d90aad", - "transactionHash": "0xdc643ffbb8e5a5bfa3362dfb0c6757ec2b944cd1d2ceb528274772bfa8e7cc1c", + "blockHash": "0x32c86631ca4fafaec4dfc9e94ec65de09a51d5abe4bc8a09ce1167543622941f", + "transactionHash": "0x5f9a808c50fb271ca8c8b605da5ee836dd814c4cf9d3ccaaea357933c2d6ae5a", "logs": [], - "blockNumber": 10111129, - "cumulativeGasUsed": "2744841", + "blockNumber": 10489661, + "cumulativeGasUsed": "9237326", "status": 1, "byzantium": true }, "args": [ "0x0630d1b8C2df3F0a68Df578D02075027a6397173", - "0x90F609c73F7498dD031e0dAfF3B40e93c04a6C60" + "0x77F19aF4614572732767B569979Bc3B407d63a68" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/rinkeby/TaskTreasuryUpgradable.json b/deployments/rinkeby/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..6fcd12ef --- /dev/null +++ b/deployments/rinkeby/TaskTreasuryUpgradable.json @@ -0,0 +1,646 @@ +{ + "address": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "transactionIndex": 1, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000020000001000000000000800000000000000000020000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000200000000000000000080000000000000000000000008000000000000000000000010000000000000000000000000000020000000000000000000000400000000000002000000000000010000000000008000", + "blockHash": "0xfb827a4115e5f818c1ef4ec648d8dff4c6da4eb348be8e4c3963aa2122bf8607", + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 10461688, + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "address": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000004f71534d1ca5794743baa5d5c1fd7acfde091c67" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xfb827a4115e5f818c1ef4ec648d8dff4c6da4eb348be8e4c3963aa2122bf8607" + }, + { + "transactionIndex": 1, + "blockNumber": 10461688, + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "address": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xfb827a4115e5f818c1ef4ec648d8dff4c6da4eb348be8e4c3963aa2122bf8607" + } + ], + "blockNumber": 10461688, + "cumulativeGasUsed": "783902", + "status": 1, + "byzantium": true + }, + "args": [ + "0x4F71534d1CA5794743BAA5D5C1Fd7AcFDE091c67", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x00" + } + ] + }, + "implementation": "0x4F71534d1CA5794743BAA5D5C1Fd7AcFDE091c67", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/rinkeby/TaskTreasuryUpgradable_Implementation.json b/deployments/rinkeby/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..c6da732b --- /dev/null +++ b/deployments/rinkeby/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,748 @@ +{ + "address": "0x4F71534d1CA5794743BAA5D5C1Fd7AcFDE091c67", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x4391589e42529d17e15cf8891a1191a09ad443e429cd2a43ff6c4e2ddb0eddbf", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x4F71534d1CA5794743BAA5D5C1Fd7AcFDE091c67", + "transactionIndex": 5, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x18194018bdaca418f9665954b1997208774e2681a9da10a9b2d5de6848f328f1", + "transactionHash": "0x4391589e42529d17e15cf8891a1191a09ad443e429cd2a43ff6c4e2ddb0eddbf", + "logs": [], + "blockNumber": 10461686, + "cumulativeGasUsed": "3697949", + "status": 1, + "byzantium": true + }, + "args": ["0x90F609c73F7498dD031e0dAfF3B40e93c04a6C60"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/rinkeby/TaskTreasuryUpgradable_Proxy.json b/deployments/rinkeby/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..068673a5 --- /dev/null +++ b/deployments/rinkeby/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,217 @@ +{ + "address": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "transactionIndex": 1, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000020000001000000000000800000000000000000020000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000200000000000000000080000000000000000000000008000000000000000000000010000000000000000000000000000020000000000000000000000400000000000002000000000000010000000000008000", + "blockHash": "0xfb827a4115e5f818c1ef4ec648d8dff4c6da4eb348be8e4c3963aa2122bf8607", + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 10461688, + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "address": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000004f71534d1ca5794743baa5d5c1fd7acfde091c67" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xfb827a4115e5f818c1ef4ec648d8dff4c6da4eb348be8e4c3963aa2122bf8607" + }, + { + "transactionIndex": 1, + "blockNumber": 10461688, + "transactionHash": "0xd1083961a2153ca7876b71600a6c4acf4091efad6399d350333f173aaecc179a", + "address": "0x77F19aF4614572732767B569979Bc3B407d63a68", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xfb827a4115e5f818c1ef4ec648d8dff4c6da4eb348be8e4c3963aa2122bf8607" + } + ], + "blockNumber": 10461688, + "cumulativeGasUsed": "783902", + "status": 1, + "byzantium": true + }, + "args": [ + "0x4F71534d1CA5794743BAA5D5C1Fd7AcFDE091c67", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/rinkeby/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/rinkeby/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/rinkeby/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/deployments/ropsten/Ops.json b/deployments/ropsten/Ops.json index 27757d3e..441c2893 100644 --- a/deployments/ropsten/Ops.json +++ b/deployments/ropsten/Ops.json @@ -5911,7 +5911,7 @@ } } ], - "implementation": "0xd1c33056041C95F2A46864827eB4CE093f9Bc579", + "implementation": "0x77c52647034f80eB18b0aDED1cFDc5Be542F34B3", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/ropsten/Ops_Implementation.json b/deployments/ropsten/Ops_Implementation.json index abda36dd..5e7326c9 100644 --- a/deployments/ropsten/Ops_Implementation.json +++ b/deployments/ropsten/Ops_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xd1c33056041C95F2A46864827eB4CE093f9Bc579", + "address": "0x77c52647034f80eB18b0aDED1cFDc5Be542F34B3", "abi": [ { "inputs": [ @@ -9,7 +9,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "_taskTreasury", "type": "address" } @@ -559,7 +559,7 @@ "name": "taskTreasury", "outputs": [ { - "internalType": "address", + "internalType": "contract ITaskTreasuryUpgradable", "name": "", "type": "address" } @@ -605,30 +605,31 @@ "type": "function" } ], - "transactionHash": "0x378134ff19f416dd2d2473a1c9d8272dcd8a191b687956bb0b81b56dc414dd06", + "transactionHash": "0x495b24a5882a9c11ef084304da4ce8c221ba90b18e4e7132c87c48284d616fcb", "receipt": { "to": null, "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", - "contractAddress": "0xd1c33056041C95F2A46864827eB4CE093f9Bc579", - "transactionIndex": 18, - "gasUsed": "2650216", + "contractAddress": "0x77c52647034f80eB18b0aDED1cFDc5Be542F34B3", + "transactionIndex": 10, + "gasUsed": "2673374", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xac6350b6bbe58ead96a801f2a20d36528522d26a1ee6fc266eb458f938a7304a", - "transactionHash": "0x378134ff19f416dd2d2473a1c9d8272dcd8a191b687956bb0b81b56dc414dd06", + "blockHash": "0x58dbf05d9e719085973e279692148712dd804572b80be288a86dc392438c32bc", + "transactionHash": "0x495b24a5882a9c11ef084304da4ce8c221ba90b18e4e7132c87c48284d616fcb", "logs": [], - "blockNumber": 11917797, - "cumulativeGasUsed": "3263287", + "blockNumber": 12187119, + "cumulativeGasUsed": "3245515", "status": 1, "byzantium": true }, "args": [ "0xCc4CcD69D31F9FfDBD3BFfDe49c6aA886DaB98d9", - "0x2705aCca70CdB3E326C1013eEA2c03A4f2935b66" + "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380" ], - "solcInputHash": "474728aa48b023738c40cc1508656900", - "metadata": "{\"compiler\":{\"version\":\"0.8.0+commit.c7dfd78e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _setOwner(_msgSender());\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _setOwner(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _setOwner(newOwner);\\n }\\n\\n function _setOwner(address newOwner) private {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0x6bb804a310218875e89d12c053e94a13a4607cdf7cc2052f3e52bd32a0dc50a1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n constructor() {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and make it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0x842ccf9a6cd33e17b7acef8372ca42090755217b358fe0c44c98e951ea549d3a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) private pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3b4820cac4f127869f6eb496c1d74fa6ac86ed24071e0f94742e6aef20e7252c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x95098bd1d9c8dec4d80d3dedb88a0d949fa0d740ee99f2aa466bc308216ca6d5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute.\\n return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2);\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x2cc1535d318fe533ffa4ad30de28f5abed305ff748bc72d0344072ac10007e29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x211639753e28bdca7f98618f51dca3dcd08a88b57c45050eb05fa4d0053327c3\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {Gelatofied} from \\\"./gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {TaskTreasury} from \\\"./taskTreasury/TaskTreasury.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n address public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, address _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n TaskTreasury(taskTreasury).useFunds(\\n _feeToken,\\n _txFee,\\n _taskCreator\\n );\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb7332f4ef72063be78bc290a3c90a42a62bfdd92d0cc501b8de5423a2be44a73\",\"license\":\"UNLICENSED\"},\"contracts/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0x8b060a6d0eef77b13d1987c100073575bbf5eb7cf792033540908e9dcc6e8f85\",\"license\":\"UNLICENSED\"},\"contracts/gelato/GelatoBytes.sol\":{\"content\":\"// \\\"SPDX-License-Identifier: UNLICENSED\\\"\\npragma solidity 0.8.0;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x439888181cf37ca3f335d9071618a69b9965e8fd87bf0ded0175aa292969296f\",\"license\":\"UNLICENSED\"},\"contracts/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x53b07cdee857f9544ff384c7da8a9bda88d007213f622918c44086f02930b222\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.0;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {\\n ReentrancyGuard\\n} from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport {_transfer, ETH} from \\\"../gelato/FGelato.sol\\\";\\n\\ncontract TaskTreasury is Ownable, ReentrancyGuard {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n mapping(address => mapping(address => uint256)) public userTokenBalance;\\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n address payable public immutable gelato;\\n\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) external payable {\\n uint256 depositAmount;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n IERC20 token = IERC20(_token);\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n depositAmount = postBalance - preBalance;\\n }\\n\\n userTokenBalance[_receiver][_token] =\\n userTokenBalance[_receiver][_token] +\\n depositAmount;\\n\\n if (!_tokenCredits[_receiver].contains(_token))\\n _tokenCredits[_receiver].add(_token);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) external nonReentrant {\\n uint256 balance = userTokenBalance[msg.sender][_token];\\n\\n uint256 withdrawAmount = Math.min(balance, _amount);\\n\\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\\n\\n _transfer(_receiver, _token, withdrawAmount);\\n\\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\\\"\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n /// @param _user Address of user whose balance will be deducted\\n function useFunds(\\n address _token,\\n uint256 _amount,\\n address _user\\n ) external onlyWhitelistedServices {\\n userTokenBalance[_user][_token] =\\n userTokenBalance[_user][_token] -\\n _amount;\\n\\n if (userTokenBalance[_user][_token] == 0)\\n _tokenCredits[_user].remove(_token);\\n\\n _transfer(gelato, _token, _amount);\\n }\\n\\n // Governance functions\\n\\n /// @notice Add new service that can call useFunds. Gelato Governance\\n /// @param _service New service to add\\n function addWhitelistedService(address _service) external onlyOwner {\\n require(\\n !_whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: whitelisted\\\"\\n );\\n _whitelistedServices.add(_service);\\n }\\n\\n /// @notice Remove old service that can call useFunds. Gelato Governance\\n /// @param _service Old service to remove\\n function removeWhitelistedService(address _service) external onlyOwner {\\n require(\\n _whitelistedServices.contains(_service),\\n \\\"TaskTreasury: addWhitelistedService: !whitelisted\\\"\\n );\\n _whitelistedServices.remove(_service);\\n }\\n\\n // View Funcs\\n\\n /// @notice Helper func to get all deposited tokens by a user\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n external\\n view\\n returns (address[] memory)\\n {\\n uint256 length = _tokenCredits[_user].length();\\n address[] memory creditTokens = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n creditTokens[i] = _tokenCredits[_user].at(i);\\n }\\n return creditTokens;\\n }\\n\\n function getWhitelistedServices() external view returns (address[] memory) {\\n uint256 length = _whitelistedServices.length();\\n address[] memory whitelistedServices = new address[](length);\\n\\n for (uint256 i; i < length; i++) {\\n whitelistedServices[i] = _whitelistedServices.at(i);\\n }\\n return whitelistedServices;\\n }\\n}\\n\",\"keccak256\":\"0x4da7f9fd46ca11b1a7ce498ef8edb3b629a20b0fa1c023a0fc38d7a88c50fbea\",\"license\":\"UNLICENSED\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620030e7380380620030e78339818101604052810190620000379190620000dd565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505050506200019a565b600081519050620000c08162000166565b92915050565b600081519050620000d78162000180565b92915050565b60008060408385031215620000f157600080fd5b60006200010185828601620000c6565b92505060206200011485828601620000af565b9150509250929050565b60006200012b8262000146565b9050919050565b60006200013f8262000146565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b62000171816200011e565b81146200017d57600080fd5b50565b6200018b8162000132565b81146200019757600080fd5b50565b60805160601c60a05160601c612f13620001d4600039600081816107e701526111a401526000818161056a015261098d0152612f136000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611e4f565b6103e9565b60405161014291906128db565b60405180910390f35b610165600480360381019061016091906121a3565b610568565b005b610181600480360381019061017c9190612067565b61091f565b60405161018e9190612747565b60405180910390f35b61019f610952565b6040516101ac919061299c565b60405180910390f35b6101bd61098b565b6040516101ca9190612762565b60405180910390f35b6101db6109af565b6040516101e89190612747565b60405180910390f35b61020b60048036038101906102069190612067565b6109d5565b6040516102189190612747565b60405180910390f35b61023b60048036038101906102369190611e78565b610a08565b60405161024891906128fd565b60405180910390f35b61026b60048036038101906102669190612090565b610a47565b6040516102789190612941565b60405180910390f35b61029b60048036038101906102969190611f01565b610a69565b6040516102a891906128fd565b60405180910390f35b6102cb60048036038101906102c691906120d5565b610cb9565b6040516102d891906128fd565b60405180910390f35b6102e9610e8d565b6040516102f7929190612ac2565b60405180910390f35b61031a60048036038101906103159190612067565b610ebe565b604051610328929190612a7e565b60405180910390f35b61034b60048036038101906103469190611f81565b610f1a565b60405161035891906128fd565b60405180910390f35b61037b60048036038101906103769190612013565b611169565b60405161038891906128fd565b60405180910390f35b61039961119c565b6040516103a69190612aa7565b60405180910390f35b6103b76111a2565b6040516103c49190612747565b60405180910390f35b6103e760048036038101906103e29190612067565b6111c6565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114a6565b905060008167ffffffffffffffff811115610478577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156104a65781602001602082028036833780820191505090505b50905060005b8281101561055d5761050581600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206114bb90919063ffffffff16565b82828151811061053e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061055590612d3b565b9150506104ac565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ed906129be565b60405180910390fd5b600061061c888561060786866114d2565b8a8b610613578d610616565b60005b8a610a08565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b590612a3e565b60405180910390fd5b8661070c578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b610715816116e0565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161073f9291906126c6565b6000604051808303816000865af19150503d806000811461077c576040519150601f19603f3d011682016040523d82523d6000602084013e610781565b606091505b5091509150811580156107915750875b156107df576107de6040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826118c390919063ffffffff16565b5b8815610879577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8c8e8d6040518463ffffffff1660e01b8152600401610842939291906128a4565b600060405180830381600087803b15801561085c57600080fd5b505af1158015610870573d6000803e3d6000fd5b505050506108a5565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a88888888604051610909949392919061295c565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000868686868686604051602001610a2596959493929190612813565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a599291906126c6565b6040518091039020905092915050565b600080610aba8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610acc3388886001600086610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b66906129de565b60405180910390fd5b610bc082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610ca79a9998979695949392919061277d565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610d0f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d06906129fe565b60405180910390fd5b8115610d2957610d228888888888610a69565b9050610d3a565b610d37888888888888610f1a565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d5b5742610d5d565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f6b8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611169565b9050610f7c33898960008786610a08565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461101f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611016906129de565b60405180910390fd5b61107082600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a2c90919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a6040516111569a9998979695949392919061277d565b60405180910390a1509695505050505050565b6000828260405160200161117e929190612874565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125d90612a5e565b60405180910390fd5b6112b781600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611a4390919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff161415611400576000611403565b60015b905080156114685760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098333604051611499929190612918565b60405180910390a1505050565b60006114b482600001611a5a565b9050919050565b60006114ca8360000183611a6b565b905092915050565b6000601883836003818110611510577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611599577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611622577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106116a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff16141561173a57600061173d565b60015b905080156118be57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156117cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c390612a1e565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff1661181a9190612bd3565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff1610611880578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826118799190612bd3565b9150611822565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516118d39190612d84565b14156119d0576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156119745760448301925081836040516020016119299291906126df565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161196b919061299c565b60405180910390fd5b816040516020016119859190612703565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119c7919061299c565b60405180910390fd5b806040516020016119e19190612725565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a23919061299c565b60405180910390fd5b6000611a3b8360000183611abc565b905092915050565b6000611a528360000183611b2c565b905092915050565b600081600001805490509050919050565b6000826000018281548110611aa9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b6000611ac88383611cb2565b611b21578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611b26565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611ca6576000600182611b5e9190612c19565b9050600060018660000180549050611b769190612c19565b9050818114611c31576000866000018281548110611bbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110611c07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611c6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611cac565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000611ce8611ce384612b1c565b612aeb565b905082815260208101848484011115611d0057600080fd5b611d0b848285612cf9565b509392505050565b600081359050611d2281612e53565b92915050565b600081359050611d3781612e6a565b92915050565b600081359050611d4c81612e81565b92915050565b600081359050611d6181612e98565b92915050565b60008083601f840112611d7957600080fd5b8235905067ffffffffffffffff811115611d9257600080fd5b602083019150836001820283011115611daa57600080fd5b9250929050565b600082601f830112611dc257600080fd5b8135611dd2848260208601611cd5565b91505092915050565b60008083601f840112611ded57600080fd5b8235905067ffffffffffffffff811115611e0657600080fd5b602083019150836001820283011115611e1e57600080fd5b9250929050565b600081359050611e3481612eaf565b92915050565b600081359050611e4981612ec6565b92915050565b600060208284031215611e6157600080fd5b6000611e6f84828501611d13565b91505092915050565b60008060008060008060c08789031215611e9157600080fd5b6000611e9f89828a01611d13565b9650506020611eb089828a01611d13565b9550506040611ec189828a01611d52565b9450506060611ed289828a01611d28565b9350506080611ee389828a01611d13565b92505060a0611ef489828a01611d3d565b9150509295509295509295565b600080600080600060808688031215611f1957600080fd5b6000611f2788828901611d13565b9550506020611f3888828901611d52565b9450506040611f4988828901611d13565b935050606086013567ffffffffffffffff811115611f6657600080fd5b611f7288828901611d67565b92509250509295509295909350565b60008060008060008060a08789031215611f9a57600080fd5b6000611fa889828a01611d13565b9650506020611fb989828a01611d52565b9550506040611fca89828a01611d13565b945050606087013567ffffffffffffffff811115611fe757600080fd5b611ff389828a01611d67565b9350935050608061200689828a01611d13565b9150509295509295509295565b6000806040838503121561202657600080fd5b600061203485828601611d13565b925050602083013567ffffffffffffffff81111561205157600080fd5b61205d85828601611db1565b9150509250929050565b60006020828403121561207957600080fd5b600061208784828501611d3d565b91505092915050565b600080602083850312156120a357600080fd5b600083013567ffffffffffffffff8111156120bd57600080fd5b6120c985828601611ddb565b92509250509250929050565b60008060008060008060008060006101008a8c0312156120f457600080fd5b60006121028c828d01611e25565b99505060206121138c828d01611e25565b98505060406121248c828d01611d13565b97505060606121358c828d01611d52565b96505060806121468c828d01611d13565b95505060a08a013567ffffffffffffffff81111561216357600080fd5b61216f8c828d01611d67565b945094505060c06121828c828d01611d13565b92505060e06121938c828d01611d28565b9150509295985092959850929598565b60008060008060008060008060006101008a8c0312156121c257600080fd5b60006121d08c828d01611e3a565b99505060206121e18c828d01611d13565b98505060406121f28c828d01611d13565b97505060606122038c828d01611d28565b96505060806122148c828d01611d28565b95505060a06122258c828d01611d3d565b94505060c06122368c828d01611d13565b93505060e08a013567ffffffffffffffff81111561225357600080fd5b61225f8c828d01611d67565b92509250509295985092959850929598565b600061227d8383612314565b60208301905092915050565b61229281612c5f565b82525050565b6122a181612c4d565b82525050565b60006122b282612b5c565b6122bc8185612b8a565b93506122c783612b4c565b8060005b838110156122f85781516122df8882612271565b97506122ea83612b7d565b9250506001810190506122cb565b5085935050505092915050565b61230e81612c71565b82525050565b61231d81612c7d565b82525050565b61232c81612c7d565b82525050565b61233b81612c87565b82525050565b600061234d8385612b9b565b935061235a838584612cf9565b61236383612e42565b840190509392505050565b600061237a8385612bac565b9350612387838584612cf9565b82840190509392505050565b600061239e82612b67565b6123a88185612b9b565b93506123b8818560208601612d08565b6123c181612e42565b840191505092915050565b60006123d782612b72565b6123e18185612bb7565b93506123f1818560208601612d08565b6123fa81612e42565b840191505092915050565b600061241082612b72565b61241a8185612bc8565b935061242a818560208601612d08565b80840191505092915050565b6000612443601783612bb7565b91507f47656c61746f666965643a204f6e6c792067656c61746f0000000000000000006000830152602082019050919050565b6000612483602c83612bb7565b91507f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008301527f73746172746564207461736b00000000000000000000000000000000000000006020830152604082019050919050565b60006124e9602a83612bb7565b91507f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008301527f616e6e6f742062652030000000000000000000000000000000000000000000006020830152604082019050919050565b600061254f601483612bb7565b91507f4f70733a20657865633a20546f6f206561726c790000000000000000000000006000830152602082019050919050565b600061258f600f83612bc8565b91507f4e6f4572726f7253656c6563746f7200000000000000000000000000000000006000830152600f82019050919050565b60006125cf601883612bb7565b91507f4f70733a20657865633a204e6f207461736b20666f756e6400000000000000006000830152602082019050919050565b600061260f602e83612bb7565b91507f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008301527f7374617274207461736b207965740000000000000000000000000000000000006020830152604082019050919050565b6000612675601483612bc8565b91507f556e657870656374656452657475726e646174610000000000000000000000006000830152601482019050919050565b6126b181612cb3565b82525050565b6126c081612cef565b82525050565b60006126d382848661236e565b91508190509392505050565b60006126eb8285612405565b91506126f78284612405565b91508190509392505050565b600061270f8284612405565b915061271a82612582565b915081905092915050565b60006127318284612405565b915061273c82612668565b915081905092915050565b600060208201905061275c6000830184612298565b92915050565b60006020820190506127776000830184612289565b92915050565b600061012082019050612793600083018d612298565b6127a0602083018c612298565b6127ad604083018b612332565b6127ba606083018a612298565b6127c76080830189612323565b81810360a08301526127da818789612341565b90506127e960c0830186612305565b6127f660e0830185612298565b612804610100830184612323565b9b9a5050505050505050505050565b600060c0820190506128286000830189612298565b6128356020830188612298565b6128426040830187612332565b61284f6060830186612305565b61285c6080830185612298565b61286960a0830184612323565b979650505050505050565b60006040820190506128896000830185612298565b818103602083015261289b8184612393565b90509392505050565b60006060820190506128b96000830186612298565b6128c660208301856126b7565b6128d36040830184612298565b949350505050565b600060208201905081810360008301526128f581846122a7565b905092915050565b60006020820190506129126000830184612323565b92915050565b600060408201905061292d6000830185612323565b61293a6020830184612298565b9392505050565b60006020820190506129566000830184612332565b92915050565b60006060820190508181036000830152612977818688612341565b90506129866020830185612323565b6129936040830184612305565b95945050505050565b600060208201905081810360008301526129b681846123cc565b905092915050565b600060208201905081810360008301526129d781612436565b9050919050565b600060208201905081810360008301526129f781612476565b9050919050565b60006020820190508181036000830152612a17816124dc565b9050919050565b60006020820190508181036000830152612a3781612542565b9050919050565b60006020820190508181036000830152612a57816125c2565b9050919050565b60006020820190508181036000830152612a7781612602565b9050919050565b6000604082019050612a9360008301856126a8565b612aa060208301846126a8565b9392505050565b6000602082019050612abc60008301846126b7565b92915050565b6000604082019050612ad760008301856126b7565b612ae46020830184612298565b9392505050565b6000604051905081810181811067ffffffffffffffff82111715612b1257612b11612e13565b5b8060405250919050565b600067ffffffffffffffff821115612b3757612b36612e13565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000612bde82612cb3565b9150612be983612cb3565b9250826fffffffffffffffffffffffffffffffff03821115612c0e57612c0d612db5565b5b828201905092915050565b6000612c2482612cef565b9150612c2f83612cef565b925082821015612c4257612c41612db5565b5b828203905092915050565b6000612c5882612ccf565b9050919050565b6000612c6a82612ccf565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b83811015612d26578082015181840152602081019050612d0b565b83811115612d35576000848401525b50505050565b6000612d4682612cef565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612d7957612d78612db5565b5b600182019050919050565b6000612d8f82612cef565b9150612d9a83612cef565b925082612daa57612da9612de4565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b612e5c81612c4d565b8114612e6757600080fd5b50565b612e7381612c71565b8114612e7e57600080fd5b50565b612e8a81612c7d565b8114612e9557600080fd5b50565b612ea181612c87565b8114612eac57600080fd5b50565b612eb881612cb3565b8114612ec357600080fd5b50565b612ecf81612cef565b8114612eda57600080fd5b5056fea2646970667358221220e8005659f27fcc9c9daf3b00bfbef000be285a36eff2030f97831d33caf2afa464736f6c63430008000033", + "numDeployments": 2, + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_gelato\",\"type\":\"address\"},{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"name\":\"_taskTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"txFee\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"execData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"callSuccess\",\"type\":\"bool\"}],\"name\":\"ExecSuccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"}],\"name\":\"TaskCancelled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"taskCreator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"execAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"resolverAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"resolverData\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"useTaskTreasuryFunds\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"resolverHash\",\"type\":\"bytes32\"}],\"name\":\"TaskCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"taskId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"nextExec\",\"type\":\"uint128\"},{\"indexed\":true,\"internalType\":\"uint128\",\"name\":\"interval\",\"type\":\"uint128\"}],\"name\":\"TimerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_taskId\",\"type\":\"bytes32\"}],\"name\":\"cancelTask\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"createTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"}],\"name\":\"createTaskNoPrepayment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint128\",\"name\":\"_startTime\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"_interval\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_execSelector\",\"type\":\"bytes4\"},{\"internalType\":\"address\",\"name\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTreasury\",\"type\":\"bool\"}],\"name\":\"createTimedTask\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"task\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_txFee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"_revertOnFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_execData\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"execAddresses\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"_resolverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_resolverData\",\"type\":\"bytes\"}],\"name\":\"getResolverHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"}],\"name\":\"getSelector\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_taskCreator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_execAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4\",\"name\":\"_selector\",\"type\":\"bytes4\"},{\"internalType\":\"bool\",\"name\":\"_useTaskTreasuryFunds\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_resolverHash\",\"type\":\"bytes32\"}],\"name\":\"getTaskId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"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\":\"taskCreator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"taskTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasuryUpgradable\",\"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\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"cancelTask(bytes32)\":{\"params\":{\"_taskId\":\"The hash of the task, can be computed using getTaskId()\"}},\"createTask(address,bytes4,address,bytes)\":{\"details\":\"Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"details\":\"Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\",\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\"}},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the transactions\",\"_execSelector\":\"Which function Gelato should eecute on the _execAddress\",\"_feeToken\":\"Which token to use as fee payment\",\"_interval\":\"After how many seconds should each task be executed\",\"_resolverAddress\":\"On which contract should Gelato check when to execute the tx\",\"_resolverData\":\"Which data should be used to check on the Resolver when to execute the tx\",\"_startTime\":\"Timestamp when the first task should become executable. 0 for right now\",\"_useTreasury\":\"True if Gelato should charge fees from TaskTreasury, false if not\"}},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"params\":{\"_execAddress\":\"On which contract should Gelato execute the tx\",\"_execData\":\"Data used to execute the tx, queried from the Resolver by Gelato\",\"_feeToken\":\"Token used to pay for the execution. ETH = 0xeeeeee...\",\"_revertOnFailure\":\"To revert or not if call to execAddress fails\",\"_taskCreator\":\"On which contract should Gelato check when to execute the tx\",\"_txFee\":\"Fee paid to Gelato for execution, deducted on the TaskTreasury\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getResolverHash(address,bytes)\":{\"params\":{\"_resolverAddress\":\"Address of resolver\",\"_resolverData\":\"Data passed to resolver\"}},\"getSelector(string)\":{\"details\":\"Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\",\"params\":{\"_func\":\"String of the function you want the selector from\"}},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"params\":{\"_execAddress\":\"Address of the contract to be executed by Gelato\",\"_feeToken\":\"FeeToken to use, address 0 if task treasury is used\",\"_resolverHash\":\"hash of resolver address and data\",\"_selector\":\"Function on the _execAddress which should be executed\",\"_taskCreator\":\"Address of the task creator\",\"_useTaskTreasuryFunds\":\"If msg.sender's balance on TaskTreasury should pay for the tx\"}},\"getTaskIdsByUser(address)\":{\"params\":{\"_taskCreator\":\"Address who created the task\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cancelTask(bytes32)\":{\"notice\":\"Cancel a task so that Gelato can no longer execute it\"},\"createTask(address,bytes4,address,bytes)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTaskNoPrepayment(address,bytes4,address,bytes,address)\":{\"notice\":\"Create a task that tells Gelato to monitor and execute transactions on specific contracts\"},\"createTimedTask(uint128,uint128,address,bytes4,address,bytes,address,bool)\":{\"notice\":\"Create a timed task that executes every so often based on the inputted interval\"},\"exec(uint256,address,address,bool,bool,bytes32,address,bytes)\":{\"notice\":\"Execution API called by Gelato\"},\"getFeeDetails()\":{\"notice\":\"Helper func to query fee and feeToken\"},\"getResolverHash(address,bytes)\":{\"notice\":\"Helper func to query the resolverHash\"},\"getSelector(string)\":{\"notice\":\"Helper func to query the _selector of a function you want to automate\"},\"getTaskId(address,address,bytes4,bool,address,bytes32)\":{\"notice\":\"Returns TaskId of a task Creator\"},\"getTaskIdsByUser(address)\":{\"notice\":\"Helper func to query all open tasks by a task creator\"}},\"notice\":\"Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactionsResolverAddresses determine when Gelato should execute and provides bots with the payload they should use to executeExecAddress determine the actual contracts to execute a function on\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Ops.sol\":\"Ops\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/Ops.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {Gelatofied} from \\\"./vendor/gelato/Gelatofied.sol\\\";\\nimport {GelatoBytes} from \\\"./vendor/gelato/GelatoBytes.sol\\\";\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"./interfaces/ITaskTreasuryUpgradable.sol\\\";\\n\\n// solhint-disable max-line-length\\n// solhint-disable max-states-count\\n// solhint-disable not-rely-on-time\\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\\n/// the payload they should use to execute\\n/// @notice ExecAddress determine the actual contracts to execute a function on\\ncontract Ops is Gelatofied {\\n using SafeERC20 for IERC20;\\n using GelatoBytes for bytes;\\n using EnumerableSet for EnumerableSet.Bytes32Set;\\n\\n struct Time {\\n uint128 nextExec;\\n uint128 interval;\\n }\\n\\n // solhint-disable const-name-snakecase\\n string public constant version = \\\"4\\\";\\n mapping(bytes32 => address) public taskCreator;\\n mapping(bytes32 => address) public execAddresses;\\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\\n ITaskTreasuryUpgradable public immutable taskTreasury;\\n uint256 public fee;\\n address public feeToken;\\n // Appended State\\n mapping(bytes32 => Time) public timedTask;\\n\\n event ExecSuccess(\\n uint256 indexed txFee,\\n address indexed feeToken,\\n address indexed execAddress,\\n bytes execData,\\n bytes32 taskId,\\n bool callSuccess\\n );\\n event TaskCreated(\\n address taskCreator,\\n address execAddress,\\n bytes4 selector,\\n address resolverAddress,\\n bytes32 taskId,\\n bytes resolverData,\\n bool useTaskTreasuryFunds,\\n address feeToken,\\n bytes32 resolverHash\\n );\\n event TaskCancelled(bytes32 taskId, address taskCreator);\\n event TimerSet(\\n bytes32 indexed taskId,\\n uint128 indexed nextExec,\\n uint128 indexed interval\\n );\\n\\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\\n Gelatofied(_gelato)\\n {\\n taskTreasury = _taskTreasury;\\n }\\n\\n /// @notice Execution API called by Gelato\\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _revertOnFailure To revert or not if call to execAddress fails\\n /// @param _execAddress On which contract should Gelato execute the tx\\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\\n // solhint-disable function-max-lines\\n // solhint-disable code-complexity\\n function exec(\\n uint256 _txFee,\\n address _feeToken,\\n address _taskCreator,\\n bool _useTaskTreasuryFunds,\\n bool _revertOnFailure,\\n bytes32 _resolverHash,\\n address _execAddress,\\n bytes calldata _execData\\n ) external onlyGelato {\\n bytes32 task = getTaskId(\\n _taskCreator,\\n _execAddress,\\n _execData.calldataSliceSelector(),\\n _useTaskTreasuryFunds,\\n _useTaskTreasuryFunds ? address(0) : _feeToken,\\n _resolverHash\\n );\\n\\n require(taskCreator[task] == _taskCreator, \\\"Ops: exec: No task found\\\");\\n\\n if (!_useTaskTreasuryFunds) {\\n fee = _txFee;\\n feeToken = _feeToken;\\n }\\n\\n _updateTime(task);\\n\\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\\n\\n // For off-chain simultaion\\n if (!success && _revertOnFailure)\\n returnData.revertWithError(\\\"Ops.exec:\\\");\\n\\n if (_useTaskTreasuryFunds) {\\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\\n } else {\\n delete fee;\\n delete feeToken;\\n }\\n\\n emit ExecSuccess(\\n _txFee,\\n _feeToken,\\n _execAddress,\\n _execData,\\n task,\\n success\\n );\\n }\\n\\n /// @notice Helper func to query fee and feeToken\\n function getFeeDetails() external view returns (uint256, address) {\\n return (fee, feeToken);\\n }\\n\\n /// @notice Helper func to query all open tasks by a task creator\\n /// @param _taskCreator Address who created the task\\n function getTaskIdsByUser(address _taskCreator)\\n external\\n view\\n returns (bytes32[] memory)\\n {\\n uint256 length = _createdTasks[_taskCreator].length();\\n bytes32[] memory taskIds = new bytes32[](length);\\n\\n for (uint256 i; i < length; i++) {\\n taskIds[i] = _createdTasks[_taskCreator].at(i);\\n }\\n\\n return taskIds;\\n }\\n\\n /// @notice Helper func to query the _selector of a function you want to automate\\n /// @param _func String of the function you want the selector from\\n /// @dev Example: \\\"transferFrom(address,address,uint256)\\\" => 0x23b872dd\\n function getSelector(string calldata _func) external pure returns (bytes4) {\\n return bytes4(keccak256(bytes(_func)));\\n }\\n\\n /// @notice Create a timed task that executes every so often based on the inputted interval\\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\\n /// @param _interval After how many seconds should each task be executed\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\\n function createTimedTask(\\n uint128 _startTime,\\n uint128 _interval,\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken,\\n bool _useTreasury\\n ) public returns (bytes32 task) {\\n require(_interval > 0, \\\"Ops: createTimedTask: interval cannot be 0\\\");\\n\\n if (_useTreasury) {\\n task = createTask(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData\\n );\\n } else {\\n task = createTaskNoPrepayment(\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n _resolverData,\\n _feeToken\\n );\\n }\\n\\n uint128 nextExec = uint256(_startTime) > block.timestamp\\n ? _startTime\\n : uint128(block.timestamp);\\n\\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\\n emit TimerSet(task, nextExec, _interval);\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n function createTask(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n true,\\n address(0),\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n true,\\n address(0),\\n resolverHash\\n );\\n }\\n\\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\\n /// @param _execAddress On which contract should Gelato execute the transactions\\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\\n /// @param _feeToken Which token to use as fee payment\\n function createTaskNoPrepayment(\\n address _execAddress,\\n bytes4 _execSelector,\\n address _resolverAddress,\\n bytes calldata _resolverData,\\n address _feeToken\\n ) public returns (bytes32 task) {\\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\\n task = getTaskId(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n\\n require(\\n taskCreator[task] == address(0),\\n \\\"Ops: createTask: Sender already started task\\\"\\n );\\n\\n _createdTasks[msg.sender].add(task);\\n taskCreator[task] = msg.sender;\\n execAddresses[task] = _execAddress;\\n\\n emit TaskCreated(\\n msg.sender,\\n _execAddress,\\n _execSelector,\\n _resolverAddress,\\n task,\\n _resolverData,\\n false,\\n _feeToken,\\n resolverHash\\n );\\n }\\n\\n /// @notice Cancel a task so that Gelato can no longer execute it\\n /// @param _taskId The hash of the task, can be computed using getTaskId()\\n function cancelTask(bytes32 _taskId) public {\\n require(\\n taskCreator[_taskId] == msg.sender,\\n \\\"Ops: cancelTask: Sender did not start task yet\\\"\\n );\\n\\n _createdTasks[msg.sender].remove(_taskId);\\n delete taskCreator[_taskId];\\n delete execAddresses[_taskId];\\n\\n Time memory time = timedTask[_taskId];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n if (isTimedTask) delete timedTask[_taskId];\\n\\n emit TaskCancelled(_taskId, msg.sender);\\n }\\n\\n /// @notice Helper func to query the resolverHash\\n /// @param _resolverAddress Address of resolver\\n /// @param _resolverData Data passed to resolver\\n function getResolverHash(\\n address _resolverAddress,\\n bytes memory _resolverData\\n ) public pure returns (bytes32) {\\n return keccak256(abi.encode(_resolverAddress, _resolverData));\\n }\\n\\n /// @notice Returns TaskId of a task Creator\\n /// @param _taskCreator Address of the task creator\\n /// @param _execAddress Address of the contract to be executed by Gelato\\n /// @param _selector Function on the _execAddress which should be executed\\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\\n /// @param _resolverHash hash of resolver address and data\\n function getTaskId(\\n address _taskCreator,\\n address _execAddress,\\n bytes4 _selector,\\n bool _useTaskTreasuryFunds,\\n address _feeToken,\\n bytes32 _resolverHash\\n ) public pure returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n _taskCreator,\\n _execAddress,\\n _selector,\\n _useTaskTreasuryFunds,\\n _feeToken,\\n _resolverHash\\n )\\n );\\n }\\n\\n function _updateTime(bytes32 task) internal {\\n Time storage time = timedTask[task];\\n bool isTimedTask = time.nextExec != 0 ? true : false;\\n\\n if (isTimedTask) {\\n require(\\n time.nextExec <= uint128(block.timestamp),\\n \\\"Ops: exec: Too early\\\"\\n );\\n // If next execution would also be executed right now, skip forward to\\n // the next execution in the future\\n uint128 nextExec = time.nextExec + time.interval;\\n uint128 timestamp = uint128(block.timestamp);\\n while (timestamp >= nextExec) {\\n nextExec = nextExec + time.interval;\\n }\\n time.nextExec = nextExec;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbca048225a92d4891b20885e33e41868d3a9a1bb5cfc978e0f3885e6c55a719b\",\"license\":\"UNLICENSED\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/GelatoBytes.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nlibrary GelatoBytes {\\n function calldataSliceSelector(bytes calldata _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function memorySliceSelector(bytes memory _bytes)\\n internal\\n pure\\n returns (bytes4 selector)\\n {\\n selector =\\n _bytes[0] |\\n (bytes4(_bytes[1]) >> 8) |\\n (bytes4(_bytes[2]) >> 16) |\\n (bytes4(_bytes[3]) >> 24);\\n }\\n\\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"))\\n );\\n }\\n } else {\\n revert(\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"))\\n );\\n }\\n }\\n\\n function returnError(bytes memory _bytes, string memory _tracingInfo)\\n internal\\n pure\\n returns (string memory)\\n {\\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\\n if (_bytes.length % 32 == 4) {\\n bytes4 selector;\\n assembly {\\n selector := mload(add(0x20, _bytes))\\n }\\n if (selector == 0x08c379a0) {\\n // Function selector for Error(string)\\n assembly {\\n _bytes := add(_bytes, 68)\\n }\\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"NoErrorSelector\\\"));\\n }\\n } else {\\n return\\n string(abi.encodePacked(_tracingInfo, \\\"UnexpectedReturndata\\\"));\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6ec59b2c6f678f3bbe186677e5970e59e46a40d22881dc813c49ffb18e417951\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/Gelatofied.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {_transfer, ETH} from \\\"./FGelato.sol\\\";\\n\\nabstract contract Gelatofied {\\n address payable public immutable gelato;\\n\\n modifier gelatofy(uint256 _amount, address _paymentToken) {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n _transfer(gelato, _paymentToken, _amount);\\n }\\n\\n modifier onlyGelato() {\\n require(msg.sender == gelato, \\\"Gelatofied: Only gelato\\\");\\n _;\\n }\\n\\n constructor(address payable _gelato) {\\n gelato = _gelato;\\n }\\n}\\n\",\"keccak256\":\"0x23215873b7034ee81d6eeb7df1a93db752eddf2096ea574f7f636fdf8523d1c3\",\"license\":\"UNLICENSED\"}},\"version\":1}", + "bytecode": "0x60c06040523480156200001157600080fd5b50604051620031563803806200315683398181016040528101906200003791906200016c565b818073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250505050620001b3565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000db82620000ae565b9050919050565b620000ed81620000ce565b8114620000f957600080fd5b50565b6000815190506200010d81620000e2565b92915050565b60006200012082620000ae565b9050919050565b6000620001348262000113565b9050919050565b620001468162000127565b81146200015257600080fd5b50565b60008151905062000166816200013b565b92915050565b60008060408385031215620001865762000185620000a9565b5b60006200019685828601620000fc565b9250506020620001a98582860162000155565b9150509250929050565b60805160a051612f6f620001e76000396000818161079b015261115801526000818161051e01526109410152612f6f6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638b92696a116100a2578063b9f45adb11610071578063b9f45adb14610331578063cabcb34914610361578063ddca3f4314610391578063e60a3213146103af578063ee8ca3b5146103cd57610116565b80638b92696a14610281578063a8738825146102b1578063b810c636146102e1578063b81cd8661461030057610116565b8063573ea575116100e9578063573ea575146101b5578063647846a5146101d35780636d2dd29f146101f15780637b4e45e91461022157806380a003ff1461025157610116565b80630407145c1461011b5780630ea65a631461014b5780632e6e0bd01461016757806354fd4d5014610197575b600080fd5b61013560048036038101906101309190611bcb565b6103e9565b6040516101429190611cc0565b60405180910390f35b61016560048036038101906101609190611de1565b61051c565b005b610181600480360381019061017c9190611eb7565b6108d3565b60405161018e9190611ef3565b60405180910390f35b61019f610906565b6040516101ac9190611fa7565b60405180910390f35b6101bd61093f565b6040516101ca9190611fea565b60405180910390f35b6101db610963565b6040516101e89190611ef3565b60405180910390f35b61020b60048036038101906102069190611eb7565b610989565b6040516102189190611ef3565b60405180910390f35b61023b6004803603810190610236919061205d565b6109bc565b60405161024891906120f9565b60405180910390f35b61026b6004803603810190610266919061216a565b6109fb565b60405161027891906121c6565b60405180910390f35b61029b600480360381019061029691906121e1565b610a1d565b6040516102a891906120f9565b60405180910390f35b6102cb60048036038101906102c691906122b1565b610c6d565b6040516102d891906120f9565b60405180910390f35b6102e9610e41565b6040516102f7929190612396565b60405180910390f35b61031a60048036038101906103159190611eb7565b610e72565b6040516103289291906123ce565b60405180910390f35b61034b600480360381019061034691906123f7565b610ece565b60405161035891906120f9565b60405180910390f35b61037b600480360381019061037691906125c1565b61111d565b60405161038891906120f9565b60405180910390f35b610399611150565b6040516103a6919061261d565b60405180910390f35b6103b7611156565b6040516103c49190612697565b60405180910390f35b6103e760048036038101906103e29190611eb7565b61117a565b005b60606000610434600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061145a565b905060008167ffffffffffffffff81111561045257610451612496565b5b6040519080825280602002602001820160405280156104805781602001602082028036833780820191505090505b50905060005b82811015610511576104df81600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061146f90919063ffffffff16565b8282815181106104f2576104f16126b2565b5b602002602001018181525050808061050990612710565b915050610486565b508092505050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a1906127a5565b60405180910390fd5b60006105d088856105bb8686611486565b8a8b6105c7578d6105ca565b60005b8a6109bc565b90508773ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161066990612811565b60405180910390fd5b866106c0578960038190555088600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b6106c9816115fc565b6000808573ffffffffffffffffffffffffffffffffffffffff1685856040516106f3929190612861565b6000604051808303816000865af19150503d8060008114610730576040519150601f19603f3d011682016040523d82523d6000602084013e610735565b606091505b5091509150811580156107455750875b15610793576107926040518060400160405280600981526020017f4f70732e657865633a0000000000000000000000000000000000000000000000815250826117df90919063ffffffff16565b5b881561082d577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a3f1233e8b8d8f6040518463ffffffff1660e01b81526004016107f69392919061287a565b600060405180830381600087803b15801561081057600080fd5b505af1158015610824573d6000803e3d6000fd5b50505050610859565b600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b8573ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff168d7fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a888888886040516108bd94939291906128fe565b60405180910390a4505050505050505050505050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040518060400160405280600181526020017f340000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008686868686866040516020016109d99695949392919061293e565b6040516020818303038152906040528051906020012090509695505050505050565b60008282604051610a0d929190612861565b6040518091039020905092915050565b600080610a6e8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610a8033888860016000866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610b23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1a90612a11565b60405180910390fd5b610b7482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550866001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333888888868989600160008a604051610c5b9a99989796959493929190612a31565b60405180910390a15095945050505050565b600080896fffffffffffffffffffffffffffffffff1611610cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cba90612b39565b60405180910390fd5b8115610cdd57610cd68888888888610a1d565b9050610cee565b610ceb888888888888610ece565b90505b6000428b6fffffffffffffffffffffffffffffffff1611610d0f5742610d11565b8a5b90506040518060400160405280826fffffffffffffffffffffffffffffffff1681526020018b6fffffffffffffffffffffffffffffffff168152506005600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff160217905550905050896fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16837f857791ec95701b6fff966bff1b5ce9a86107aeabaf6d2fdfd89993aa0f084e3760405160405180910390a4509998505050505050505050565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b600080610f1f8686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061111d565b9050610f30338989600087866109bc565b9150600073ffffffffffffffffffffffffffffffffffffffff1660008084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fca90612a11565b60405180910390fd5b61102482600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061194890919063ffffffff16565b503360008084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876001600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fcfd64545826fbe236e660141349bd1ed0b30c9bec7e213894afd7745a1f76f3333898989868a8a60008b8a60405161110a9a99989796959493929190612a31565b60405180910390a1509695505050505050565b60008282604051602001611132929190612b9d565b60405160208183030381529060405280519060200120905092915050565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461121a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121190612c3f565b60405180910390fd5b61126b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061195f90919063ffffffff16565b5060008082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600560008381526020019081526020016000206040518060400160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681525050905060008082600001516fffffffffffffffffffffffffffffffff1614156113b45760006113b7565b60015b9050801561141c5760056000848152602001908152602001600020600080820160006101000a8154906fffffffffffffffffffffffffffffffff02191690556000820160106101000a8154906fffffffffffffffffffffffffffffffff021916905550505b7f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b09833360405161144d929190612c5f565b60405180910390a1505050565b600061146882600001611976565b9050919050565b600061147e8360000183611987565b905092915050565b600060188383600381811061149e5761149d6126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c601084846002818110611501576115006126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c600885856001818110611564576115636126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c858560008181106115c5576115c46126b2565b5b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916171717905092915050565b60006005600083815260200190815260200160002090506000808260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff161415611656576000611659565b60015b905080156117da57426fffffffffffffffffffffffffffffffff168260000160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1611156116e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116df90612cd4565b60405180910390fd5b60008260000160109054906101000a90046fffffffffffffffffffffffffffffffff168360000160009054906101000a90046fffffffffffffffffffffffffffffffff166117369190612cf4565b905060004290505b816fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff161061179c578360000160109054906101000a90046fffffffffffffffffffffffffffffffff16826117959190612cf4565b915061173e565b818460000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050505b505050565b6004602083516117ef9190612d69565b14156118ec576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415611890576044830192508183604051602001611845929190612dd6565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118879190611fa7565b60405180910390fd5b816040516020016118a19190612e46565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118e39190611fa7565b60405180910390fd5b806040516020016118fd9190612eb4565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161193f9190611fa7565b60405180910390fd5b600061195783600001836119b2565b905092915050565b600061196e8360000183611a22565b905092915050565b600081600001805490509050919050565b600082600001828154811061199f5761199e6126b2565b5b9060005260206000200154905092915050565b60006119be8383611b36565b611a17578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611a1c565b600090505b92915050565b60008083600101600084815260200190815260200160002054905060008114611b2a576000600182611a549190612ed6565b9050600060018660000180549050611a6c9190612ed6565b9050818114611adb576000866000018281548110611a8d57611a8c6126b2565b5b9060005260206000200154905080876000018481548110611ab157611ab06126b2565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480611aef57611aee612f0a565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611b30565b60009150505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611b9882611b6d565b9050919050565b611ba881611b8d565b8114611bb357600080fd5b50565b600081359050611bc581611b9f565b92915050565b600060208284031215611be157611be0611b63565b5b6000611bef84828501611bb6565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b611c3781611c24565b82525050565b6000611c498383611c2e565b60208301905092915050565b6000602082019050919050565b6000611c6d82611bf8565b611c778185611c03565b9350611c8283611c14565b8060005b83811015611cb3578151611c9a8882611c3d565b9750611ca583611c55565b925050600181019050611c86565b5085935050505092915050565b60006020820190508181036000830152611cda8184611c62565b905092915050565b6000819050919050565b611cf581611ce2565b8114611d0057600080fd5b50565b600081359050611d1281611cec565b92915050565b60008115159050919050565b611d2d81611d18565b8114611d3857600080fd5b50565b600081359050611d4a81611d24565b92915050565b611d5981611c24565b8114611d6457600080fd5b50565b600081359050611d7681611d50565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112611da157611da0611d7c565b5b8235905067ffffffffffffffff811115611dbe57611dbd611d81565b5b602083019150836001820283011115611dda57611dd9611d86565b5b9250929050565b60008060008060008060008060006101008a8c031215611e0457611e03611b63565b5b6000611e128c828d01611d03565b9950506020611e238c828d01611bb6565b9850506040611e348c828d01611bb6565b9750506060611e458c828d01611d3b565b9650506080611e568c828d01611d3b565b95505060a0611e678c828d01611d67565b94505060c0611e788c828d01611bb6565b93505060e08a013567ffffffffffffffff811115611e9957611e98611b68565b5b611ea58c828d01611d8b565b92509250509295985092959850929598565b600060208284031215611ecd57611ecc611b63565b5b6000611edb84828501611d67565b91505092915050565b611eed81611b8d565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611f48578082015181840152602081019050611f2d565b83811115611f57576000848401525b50505050565b6000601f19601f8301169050919050565b6000611f7982611f0e565b611f838185611f19565b9350611f93818560208601611f2a565b611f9c81611f5d565b840191505092915050565b60006020820190508181036000830152611fc18184611f6e565b905092915050565b6000611fd482611b6d565b9050919050565b611fe481611fc9565b82525050565b6000602082019050611fff6000830184611fdb565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61203a81612005565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60008060008060008060c0878903121561207a57612079611b63565b5b600061208889828a01611bb6565b965050602061209989828a01611bb6565b95505060406120aa89828a01612048565b94505060606120bb89828a01611d3b565b93505060806120cc89828a01611bb6565b92505060a06120dd89828a01611d67565b9150509295509295509295565b6120f381611c24565b82525050565b600060208201905061210e60008301846120ea565b92915050565b60008083601f84011261212a57612129611d7c565b5b8235905067ffffffffffffffff81111561214757612146611d81565b5b60208301915083600182028301111561216357612162611d86565b5b9250929050565b6000806020838503121561218157612180611b63565b5b600083013567ffffffffffffffff81111561219f5761219e611b68565b5b6121ab85828601612114565b92509250509250929050565b6121c081612005565b82525050565b60006020820190506121db60008301846121b7565b92915050565b6000806000806000608086880312156121fd576121fc611b63565b5b600061220b88828901611bb6565b955050602061221c88828901612048565b945050604061222d88828901611bb6565b935050606086013567ffffffffffffffff81111561224e5761224d611b68565b5b61225a88828901611d8b565b92509250509295509295909350565b60006fffffffffffffffffffffffffffffffff82169050919050565b61228e81612269565b811461229957600080fd5b50565b6000813590506122ab81612285565b92915050565b60008060008060008060008060006101008a8c0312156122d4576122d3611b63565b5b60006122e28c828d0161229c565b99505060206122f38c828d0161229c565b98505060406123048c828d01611bb6565b97505060606123158c828d01612048565b96505060806123268c828d01611bb6565b95505060a08a013567ffffffffffffffff81111561234757612346611b68565b5b6123538c828d01611d8b565b945094505060c06123668c828d01611bb6565b92505060e06123778c828d01611d3b565b9150509295985092959850929598565b61239081611ce2565b82525050565b60006040820190506123ab6000830185612387565b6123b86020830184611ee4565b9392505050565b6123c881612269565b82525050565b60006040820190506123e360008301856123bf565b6123f060208301846123bf565b9392505050565b60008060008060008060a0878903121561241457612413611b63565b5b600061242289828a01611bb6565b965050602061243389828a01612048565b955050604061244489828a01611bb6565b945050606087013567ffffffffffffffff81111561246557612464611b68565b5b61247189828a01611d8b565b9350935050608061248489828a01611bb6565b9150509295509295509295565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124ce82611f5d565b810181811067ffffffffffffffff821117156124ed576124ec612496565b5b80604052505050565b6000612500611b59565b905061250c82826124c5565b919050565b600067ffffffffffffffff82111561252c5761252b612496565b5b61253582611f5d565b9050602081019050919050565b82818337600083830152505050565b600061256461255f84612511565b6124f6565b9050828152602081018484840111156125805761257f612491565b5b61258b848285612542565b509392505050565b600082601f8301126125a8576125a7611d7c565b5b81356125b8848260208601612551565b91505092915050565b600080604083850312156125d8576125d7611b63565b5b60006125e685828601611bb6565b925050602083013567ffffffffffffffff81111561260757612606611b68565b5b61261385828601612593565b9150509250929050565b60006020820190506126326000830184612387565b92915050565b6000819050919050565b600061265d61265861265384611b6d565b612638565b611b6d565b9050919050565b600061266f82612642565b9050919050565b600061268182612664565b9050919050565b61269181612676565b82525050565b60006020820190506126ac6000830184612688565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061271b82611ce2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561274e5761274d6126e1565b5b600182019050919050565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b600061278f601783611f19565b915061279a82612759565b602082019050919050565b600060208201905081810360008301526127be81612782565b9050919050565b7f4f70733a20657865633a204e6f207461736b20666f756e640000000000000000600082015250565b60006127fb601883611f19565b9150612806826127c5565b602082019050919050565b6000602082019050818103600083015261282a816127ee565b9050919050565b600081905092915050565b60006128488385612831565b9350612855838584612542565b82840190509392505050565b600061286e82848661283c565b91508190509392505050565b600060608201905061288f6000830186611ee4565b61289c6020830185611ee4565b6128a96040830184612387565b949350505050565b600082825260208201905092915050565b60006128ce83856128b1565b93506128db838584612542565b6128e483611f5d565b840190509392505050565b6128f881611d18565b82525050565b600060608201905081810360008301526129198186886128c2565b905061292860208301856120ea565b61293560408301846128ef565b95945050505050565b600060c0820190506129536000830189611ee4565b6129606020830188611ee4565b61296d60408301876121b7565b61297a60608301866128ef565b6129876080830185611ee4565b61299460a08301846120ea565b979650505050505050565b7f4f70733a206372656174655461736b3a2053656e64657220616c72656164792060008201527f73746172746564207461736b0000000000000000000000000000000000000000602082015250565b60006129fb602c83611f19565b9150612a068261299f565b604082019050919050565b60006020820190508181036000830152612a2a816129ee565b9050919050565b600061012082019050612a47600083018d611ee4565b612a54602083018c611ee4565b612a61604083018b6121b7565b612a6e606083018a611ee4565b612a7b60808301896120ea565b81810360a0830152612a8e8187896128c2565b9050612a9d60c08301866128ef565b612aaa60e0830185611ee4565b612ab86101008301846120ea565b9b9a5050505050505050505050565b7f4f70733a2063726561746554696d65645461736b3a20696e74657276616c206360008201527f616e6e6f74206265203000000000000000000000000000000000000000000000602082015250565b6000612b23602a83611f19565b9150612b2e82612ac7565b604082019050919050565b60006020820190508181036000830152612b5281612b16565b9050919050565b600081519050919050565b6000612b6f82612b59565b612b7981856128b1565b9350612b89818560208601611f2a565b612b9281611f5d565b840191505092915050565b6000604082019050612bb26000830185611ee4565b8181036020830152612bc48184612b64565b90509392505050565b7f4f70733a2063616e63656c5461736b3a2053656e64657220646964206e6f742060008201527f7374617274207461736b20796574000000000000000000000000000000000000602082015250565b6000612c29602e83611f19565b9150612c3482612bcd565b604082019050919050565b60006020820190508181036000830152612c5881612c1c565b9050919050565b6000604082019050612c7460008301856120ea565b612c816020830184611ee4565b9392505050565b7f4f70733a20657865633a20546f6f206561726c79000000000000000000000000600082015250565b6000612cbe601483611f19565b9150612cc982612c88565b602082019050919050565b60006020820190508181036000830152612ced81612cb1565b9050919050565b6000612cff82612269565b9150612d0a83612269565b9250826fffffffffffffffffffffffffffffffff03821115612d2f57612d2e6126e1565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612d7482611ce2565b9150612d7f83611ce2565b925082612d8f57612d8e612d3a565b5b828206905092915050565b600081905092915050565b6000612db082611f0e565b612dba8185612d9a565b9350612dca818560208601611f2a565b80840191505092915050565b6000612de28285612da5565b9150612dee8284612da5565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b6000612e30600f83612d9a565b9150612e3b82612dfa565b600f82019050919050565b6000612e528284612da5565b9150612e5d82612e23565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b6000612e9e601483612d9a565b9150612ea982612e68565b601482019050919050565b6000612ec08284612da5565b9150612ecb82612e91565b915081905092915050565b6000612ee182611ce2565b9150612eec83611ce2565b925082821015612eff57612efe6126e1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea26469706673582212203ecf88645d63a5e4d09d50d759f0b555fe719d0b2b2ca0e2b5c0ab1a605c666d64736f6c634300080c0033", "devdoc": { "kind": "dev", "methods": { @@ -749,7 +750,7 @@ "storageLayout": { "storage": [ { - "astId": 1427, + "astId": 1883, "contract": "contracts/Ops.sol:Ops", "label": "taskCreator", "offset": 0, @@ -757,7 +758,7 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1431, + "astId": 1887, "contract": "contracts/Ops.sol:Ops", "label": "execAddresses", "offset": 0, @@ -765,15 +766,15 @@ "type": "t_mapping(t_bytes32,t_address)" }, { - "astId": 1436, + "astId": 1892, "contract": "contracts/Ops.sol:Ops", "label": "_createdTasks", "offset": 0, "slot": "2", - "type": "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)" + "type": "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)" }, { - "astId": 1440, + "astId": 1897, "contract": "contracts/Ops.sol:Ops", "label": "fee", "offset": 0, @@ -781,7 +782,7 @@ "type": "t_uint256" }, { - "astId": 1442, + "astId": 1899, "contract": "contracts/Ops.sol:Ops", "label": "feeToken", "offset": 0, @@ -789,12 +790,12 @@ "type": "t_address" }, { - "astId": 1447, + "astId": 1904, "contract": "contracts/Ops.sol:Ops", "label": "timedTask", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(Time)1420_storage)" + "type": "t_mapping(t_bytes32,t_struct(Time)1876_storage)" } ], "types": { @@ -814,12 +815,12 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_mapping(t_address,t_struct(Bytes32Set)1053_storage)": { + "t_mapping(t_address,t_struct(Bytes32Set)1433_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct EnumerableSet.Bytes32Set)", "numberOfBytes": "32", - "value": "t_struct(Bytes32Set)1053_storage" + "value": "t_struct(Bytes32Set)1433_storage" }, "t_mapping(t_bytes32,t_address)": { "encoding": "mapping", @@ -828,12 +829,12 @@ "numberOfBytes": "32", "value": "t_address" }, - "t_mapping(t_bytes32,t_struct(Time)1420_storage)": { + "t_mapping(t_bytes32,t_struct(Time)1876_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Ops.Time)", "numberOfBytes": "32", - "value": "t_struct(Time)1420_storage" + "value": "t_struct(Time)1876_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -842,27 +843,27 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_struct(Bytes32Set)1053_storage": { + "t_struct(Bytes32Set)1433_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Bytes32Set", "members": [ { - "astId": 1052, + "astId": 1432, "contract": "contracts/Ops.sol:Ops", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)873_storage" + "type": "t_struct(Set)1239_storage" } ], "numberOfBytes": "64" }, - "t_struct(Set)873_storage": { + "t_struct(Set)1239_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 868, + "astId": 1234, "contract": "contracts/Ops.sol:Ops", "label": "_values", "offset": 0, @@ -870,7 +871,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 872, + "astId": 1238, "contract": "contracts/Ops.sol:Ops", "label": "_indexes", "offset": 0, @@ -880,12 +881,12 @@ ], "numberOfBytes": "64" }, - "t_struct(Time)1420_storage": { + "t_struct(Time)1876_storage": { "encoding": "inplace", "label": "struct Ops.Time", "members": [ { - "astId": 1417, + "astId": 1873, "contract": "contracts/Ops.sol:Ops", "label": "nextExec", "offset": 0, @@ -893,7 +894,7 @@ "type": "t_uint128" }, { - "astId": 1419, + "astId": 1875, "contract": "contracts/Ops.sol:Ops", "label": "interval", "offset": 16, diff --git a/deployments/ropsten/TaskTreasuryUpgradable.json b/deployments/ropsten/TaskTreasuryUpgradable.json new file mode 100644 index 00000000..3dd010f6 --- /dev/null +++ b/deployments/ropsten/TaskTreasuryUpgradable.json @@ -0,0 +1,646 @@ +{ + "address": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } + ], + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "transactionIndex": 0, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000200000000000000000084000000000000001000020000000000000000000000000010000000000000000000000000000020080000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0xf205ec1f0ab0281342107ef30077e8b0aacab4d2537a25690b5cc81e3783df19", + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 12170551, + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "address": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000f278d2e1c82fe85e03dd97c46f22e860f90d564" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xf205ec1f0ab0281342107ef30077e8b0aacab4d2537a25690b5cc81e3783df19" + }, + { + "transactionIndex": 0, + "blockNumber": 12170551, + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "address": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xf205ec1f0ab0281342107ef30077e8b0aacab4d2537a25690b5cc81e3783df19" + } + ], + "blockNumber": 12170551, + "cumulativeGasUsed": "762902", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0f278d2E1C82fE85e03DD97c46F22e860F90D564", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "execute": { + "methodName": "initialize", + "args": [ + { + "type": "BigNumber", + "hex": "0x00" + } + ] + }, + "implementation": "0x0f278d2E1C82fE85e03DD97c46F22e860F90D564", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/ropsten/TaskTreasuryUpgradable_Implementation.json b/deployments/ropsten/TaskTreasuryUpgradable_Implementation.json new file mode 100644 index 00000000..91689a11 --- /dev/null +++ b/deployments/ropsten/TaskTreasuryUpgradable_Implementation.json @@ -0,0 +1,748 @@ +{ + "address": "0x0f278d2E1C82fE85e03DD97c46F22e860F90D564", + "abi": [ + { + "inputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "_oldTreasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FundsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "executor", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fees", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "service", + "type": "address" + } + ], + "name": "LogDeductFees", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "maxFee", + "type": "uint256" + } + ], + "name": "UpdatedMaxFee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "service", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "add", + "type": "bool" + } + ], + "name": "UpdatedService", + "type": "event" + }, + { + "inputs": [], + "name": "MIN_SHARES_IN_TREASURY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "depositFunds", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + } + ], + "name": "getTotalCreditTokensByUser", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWhitelistedServices", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_maxFee", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "maxFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oldTreasury", + "outputs": [ + { + "internalType": "contract ITaskTreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "shares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "totalShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "totalUserTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_newMaxFee", + "type": "uint256" + } + ], + "name": "updateMaxFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_service", + "type": "address" + }, + { + "internalType": "bool", + "name": "_add", + "type": "bool" + } + ], + "name": "updateWhitelistedService", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "useFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_user", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "userTokenBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdrawFunds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x97fb4c933e819f6a1e953a138031360effb053683ae5f6e6b45dfd37baa65a96", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0x0f278d2E1C82fE85e03DD97c46F22e860F90D564", + "transactionIndex": 0, + "gasUsed": "3294713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x34a25a91657b87d4f962e07c9e3309d4412c4fd593d48a6c6fcfbcb343ea79b2", + "transactionHash": "0x97fb4c933e819f6a1e953a138031360effb053683ae5f6e6b45dfd37baa65a96", + "logs": [], + "blockNumber": 12170550, + "cumulativeGasUsed": "3294713", + "status": 1, + "byzantium": true + }, + "args": ["0x2705aCca70CdB3E326C1013eEA2c03A4f2935b66"], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"_oldTreasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"initiator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"executor\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"}],\"name\":\"LogDeductFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"maxFee\",\"type\":\"uint256\"}],\"name\":\"UpdatedMaxFee\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"service\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"add\",\"type\":\"bool\"}],\"name\":\"UpdatedService\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MIN_SHARES_IN_TREASURY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"depositFunds\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"}],\"name\":\"getTotalCreditTokensByUser\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWhitelistedServices\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_maxFee\",\"type\":\"uint256\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oldTreasury\",\"outputs\":[{\"internalType\":\"contract ITaskTreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"shares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"totalShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"totalUserTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newMaxFee\",\"type\":\"uint256\"}],\"name\":\"updateMaxFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_service\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_add\",\"type\":\"bool\"}],\"name\":\"updateWhitelistedService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"useFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"userTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}},\"getCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"getTotalCreditTokensByUser(address)\":{\"params\":{\"_user\":\"User to get the balances from\"}},\"totalUserTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"updateMaxFee(uint256)\":{\"params\":{\"_newMaxFee\":\"New Max Fee to charge\"}},\"updateWhitelistedService(address,bool)\":{\"params\":{\"_add\":\"Add to whitelist if true, else remove from whitelist\",\"_service\":\"Service to add or remove from whitelist\"}},\"useFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be deducted\",\"_token\":\"Token to be used for payment by users\",\"_user\":\"Address of user whose balance will be deducted\"}},\"userTokenBalance(address,address)\":{\"params\":{\"_token\":\"Token to check balance of\",\"_user\":\"User to get balance from\"}},\"withdrawFunds(address,address,uint256)\":{\"params\":{\"_amount\":\"Amount to be credited\",\"_receiver\":\"Address receiving the credits\",\"_token\":\"Token to be credited, use \\\"0xeeee....\\\" for ETH\"}}},\"stateVariables\":{\"_tokens\":{\"details\":\"tracks the tokens deposited by users\"},\"shares\":{\"details\":\"tracks token shares of users\"},\"totalShares\":{\"details\":\"tracks total shares of tokens\"}},\"version\":1},\"userdoc\":{\"events\":{\"FundsDeposited(address,address,uint256)\":{\"notice\":\"Events ///\"}},\"kind\":\"user\",\"methods\":{\"depositFunds(address,address,uint256)\":{\"notice\":\"Function to deposit Funds which will be used to execute transactions on various services\"},\"getCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user.\"},\"getTotalCreditTokensByUser(address)\":{\"notice\":\"Helper func to get all deposited tokens by a user across treasuries.\"},\"getWhitelistedServices()\":{\"notice\":\"Get list of services that can call useFunds.\"},\"totalUserTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user across treasuries\"},\"updateMaxFee(uint256)\":{\"notice\":\"Change maxFee charged by Gelato (only relevant on Layer2s)\"},\"updateWhitelistedService(address,bool)\":{\"notice\":\"Add or remove service that can call useFunds. Gelato Governance\"},\"useFunds(address,address,uint256)\":{\"notice\":\"Function called by whitelisted services to handle payments, e.g. Gelato Ops\"},\"userTokenBalance(address,address)\":{\"notice\":\"Get balance of a token owned by user\"},\"withdrawFunds(address,address,uint256)\":{\"notice\":\"Function to withdraw Funds back to the _receiver\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":\"TaskTreasuryUpgradable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant _NOT_ENTERED = 1;\\n uint256 private constant _ENTERED = 2;\\n\\n uint256 private _status;\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n _status = _NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n // On the first call to nonReentrant, _notEntered will be true\\n require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n // Any calls to nonReentrant after this point will fail\\n _status = _ENTERED;\\n\\n _;\\n\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n _status = _NOT_ENTERED;\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0xf3a9b766b0d0456f79d9402db4b49bb16c414f3f9d65244475c0704b6c66dcf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbbc8ac883ac3c0078ce5ad3e288fbb3ffcc8a30c3a98c0fda0114d64fc44fca2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x2ccf9d2313a313d41a791505f2b5abfdc62191b5d4334f7f7a82691c088a1c87\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x9772845c886f87a3aab315f8d6b68aa599027c20f441b131cd4afaf65b588900\",\"license\":\"MIT\"},\"contracts/interfaces/IERC20Extended.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Extended {\\n function decimals() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender)\\n external\\n view\\n returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(\\n address indexed owner,\\n address indexed spender,\\n uint256 value\\n );\\n}\\n\",\"keccak256\":\"0xdfa1185ee541ba2ef0ef3cfe61fc277233ae557a90d2cb013546e01df7364695\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasury.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasury {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address token,\\n uint256 amount,\\n address user\\n ) external;\\n\\n function addWhitelistedService(address service) external;\\n\\n function removeWhitelistedService(address service) external;\\n\\n /// @notice External view functions ///\\n\\n function gelato() external view returns (address);\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xd3a9a4df2a2cb7b86802e1e7e31803283199e98955733c2744873e943497b1c4\",\"license\":\"MIT\"},\"contracts/interfaces/ITaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITaskTreasuryUpgradable {\\n /// @notice Events ///\\n event FundsDeposited(\\n address indexed sender,\\n address indexed token,\\n uint256 indexed amount\\n );\\n\\n event FundsWithdrawn(\\n address indexed receiver,\\n address indexed initiator,\\n address indexed token,\\n uint256 amount\\n );\\n\\n event LogDeductFees(\\n address indexed user,\\n address indexed executor,\\n address indexed token,\\n uint256 fees,\\n address service\\n );\\n\\n event UpdatedService(address indexed service, bool add);\\n\\n event UpdatedMaxFee(uint256 indexed maxFee);\\n\\n /// @notice External functions ///\\n\\n function depositFunds(\\n address receiver,\\n address token,\\n uint256 amount\\n ) external payable;\\n\\n function withdrawFunds(\\n address payable receiver,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function useFunds(\\n address user,\\n address token,\\n uint256 amount\\n ) external;\\n\\n function updateMaxFee(uint256 _newMaxFee) external;\\n\\n function updateWhitelistedService(address service, bool isWhitelist)\\n external;\\n\\n /// @notice External view functions ///\\n\\n function getCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getTotalCreditTokensByUser(address user)\\n external\\n view\\n returns (address[] memory);\\n\\n function getWhitelistedServices() external view returns (address[] memory);\\n\\n function totalUserTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n\\n function userTokenBalance(address user, address token)\\n external\\n view\\n returns (uint256);\\n}\\n\",\"keccak256\":\"0xa1452289581534124391c5f5c2a76048013e3a5c700824531c61476527562ba4\",\"license\":\"MIT\"},\"contracts/libraries/LibShares.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\nimport {ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {IERC20Extended} from \\\"../interfaces/IERC20Extended.sol\\\";\\n\\nlibrary LibShares {\\n function contractBalance(address _token) internal view returns (uint256) {\\n if (_token == ETH) {\\n return address(this).balance;\\n } else {\\n return IERC20Extended(_token).balanceOf(address(this));\\n }\\n }\\n\\n function tokenToShares(\\n address _token,\\n uint256 _tokenAmount,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal view returns (uint256) {\\n uint256 sharesOfToken;\\n\\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\\n\\n // credit shares equivalent to token amount\\n if (_totalShares == 0 || _totalBalance == 0) {\\n sharesOfToken = tokenIn18Dp;\\n } else {\\n sharesOfToken = divCeil(\\n tokenIn18Dp * _totalShares,\\n totalBalanceIn18Dp\\n );\\n }\\n\\n return sharesOfToken;\\n }\\n\\n function to18Dp(address _token, uint256 _amount)\\n internal\\n view\\n returns (uint256)\\n {\\n if (_token == ETH) return _amount;\\n uint256 decimals = IERC20Extended(_token).decimals();\\n\\n if (decimals < 18) {\\n return _amount * 10**(18 - decimals);\\n } else {\\n return _amount / 10**(decimals - 18);\\n }\\n }\\n\\n function sharesToToken(\\n uint256 _shares,\\n uint256 _totalShares,\\n uint256 _totalBalance\\n ) internal pure returns (uint256) {\\n uint256 tokenOfShares;\\n\\n if (_totalShares == 0 || _totalBalance == 0) {\\n tokenOfShares = 0;\\n } else {\\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\\n }\\n\\n return tokenOfShares;\\n }\\n\\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\\n uint256 remainder = x % y;\\n uint256 result;\\n\\n if (remainder == 0) {\\n result = x / y;\\n } else {\\n result = ((x - remainder) + y) / y;\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0xbb062b01df7f9afa11b37ff9ccdf62f98e4b057736cf624e83f5eb016899d59b\",\"license\":\"UNLICENSED\"},\"contracts/taskTreasury/TaskTreasuryUpgradable.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity 0.8.12;\\n\\nimport {\\n EnumerableSet\\n} from \\\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\\\";\\nimport {\\n IERC20,\\n SafeERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {\\n ReentrancyGuardUpgradeable\\n} from \\\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\\\";\\nimport {\\n Initializable\\n} from \\\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\\\";\\nimport {_transfer, ETH} from \\\"../vendor/gelato/FGelato.sol\\\";\\nimport {Proxied} from \\\"../vendor/proxy/EIP173/Proxied.sol\\\";\\nimport {ITaskTreasury} from \\\"../interfaces/ITaskTreasury.sol\\\";\\nimport {\\n ITaskTreasuryUpgradable\\n} from \\\"../interfaces/ITaskTreasuryUpgradable.sol\\\";\\nimport {LibShares} from \\\"../libraries/LibShares.sol\\\";\\n\\ncontract TaskTreasuryUpgradable is\\n ITaskTreasuryUpgradable,\\n Proxied,\\n Initializable,\\n ReentrancyGuardUpgradeable\\n{\\n using EnumerableSet for EnumerableSet.AddressSet;\\n using SafeERC20 for IERC20;\\n\\n ITaskTreasury public immutable oldTreasury;\\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\\n uint256 public maxFee;\\n\\n ///@dev tracks token shares of users\\n mapping(address => mapping(address => uint256)) public shares;\\n\\n ///@dev tracks total shares of tokens\\n mapping(address => uint256) public totalShares;\\n\\n ///@dev tracks the tokens deposited by users\\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\\n\\n EnumerableSet.AddressSet internal _whitelistedServices;\\n\\n modifier onlyWhitelistedServices() {\\n require(\\n _whitelistedServices.contains(msg.sender),\\n \\\"TaskTreasury: onlyWhitelistedServices\\\"\\n );\\n _;\\n }\\n\\n constructor(ITaskTreasury _oldTreasury) {\\n oldTreasury = _oldTreasury;\\n }\\n\\n receive() external payable {\\n depositFunds(msg.sender, ETH, msg.value);\\n }\\n\\n function initialize(uint256 _maxFee) external initializer {\\n maxFee = _maxFee;\\n __ReentrancyGuard_init();\\n }\\n\\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\\n /// @param _user Address of user whose balance will be deducted\\n /// @param _token Token to be used for payment by users\\n /// @param _amount Amount to be deducted\\n function useFunds(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) external override onlyWhitelistedServices {\\n if (maxFee != 0)\\n require(maxFee >= _amount, \\\"TaskTreasury: Overcharged\\\");\\n\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n if (_amount <= balanceInOld) {\\n oldTreasury.useFunds(_token, _amount, _user);\\n } else {\\n if (balanceInOld > 0)\\n oldTreasury.useFunds(_token, balanceInOld, _user);\\n\\n _pay(_user, _token, _amount - balanceInOld);\\n }\\n\\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\\n }\\n\\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\\n /// @param _newMaxFee New Max Fee to charge\\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\\n maxFee = _newMaxFee;\\n\\n emit UpdatedMaxFee(_newMaxFee);\\n }\\n\\n /// @notice Add or remove service that can call useFunds. Gelato Governance\\n /// @param _service Service to add or remove from whitelist\\n /// @param _add Add to whitelist if true, else remove from whitelist\\n function updateWhitelistedService(address _service, bool _add)\\n external\\n override\\n onlyProxyAdmin\\n {\\n if (_add) {\\n _whitelistedServices.add(_service);\\n } else {\\n _whitelistedServices.remove(_service);\\n }\\n\\n emit UpdatedService(_service, _add);\\n }\\n\\n /// @notice Get list of services that can call useFunds.\\n function getWhitelistedServices()\\n external\\n view\\n override\\n returns (address[] memory)\\n {\\n return _whitelistedServices.values();\\n }\\n\\n // solhint-disable max-line-length\\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function depositFunds(\\n address _receiver,\\n address _token,\\n uint256 _amount\\n ) public payable override nonReentrant {\\n uint256 depositAmount;\\n uint256 totalBalance;\\n if (_token == ETH) {\\n depositAmount = msg.value;\\n } else {\\n require(msg.value == 0, \\\"TaskTreasury: No ETH\\\");\\n IERC20 token = IERC20(_token);\\n\\n uint256 preBalance = token.balanceOf(address(this));\\n token.safeTransferFrom(msg.sender, address(this), _amount);\\n uint256 postBalance = token.balanceOf(address(this));\\n\\n depositAmount = postBalance - preBalance;\\n }\\n\\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\\n\\n _creditUser(_receiver, _token, depositAmount, totalBalance);\\n\\n emit FundsDeposited(_receiver, _token, depositAmount);\\n }\\n\\n /// @notice Function to withdraw Funds back to the _receiver\\n /// @param _receiver Address receiving the credits\\n /// @param _token Token to be credited, use \\\"0xeeee....\\\" for ETH\\n /// @param _amount Amount to be credited\\n function withdrawFunds(\\n address payable _receiver,\\n address _token,\\n uint256 _amount\\n ) public override nonReentrant {\\n _deductUser(msg.sender, _token, _amount);\\n\\n _transfer(_receiver, _token, _amount);\\n\\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user.\\n /// @param _user User to get the balances from\\n function getCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n return _tokens[_user].values();\\n }\\n\\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\\n /// @param _user User to get the balances from\\n function getTotalCreditTokensByUser(address _user)\\n public\\n view\\n override\\n returns (address[] memory)\\n {\\n address[] memory tokensInNew = _tokens[_user].values();\\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\\n\\n uint256 tokensInOldOnlyLength;\\n for (uint256 i; i < tokensInOld.length; i++) {\\n if (!_tokens[_user].contains(tokensInOld[i])) {\\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\\n tokensInOldOnlyLength++;\\n }\\n }\\n\\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\\n address[] memory tokens = new address[](uniqTokensLength);\\n\\n for (uint256 i; i < uniqTokensLength; i++) {\\n if (i < tokensInNew.length) {\\n tokens[i] = tokensInNew[i];\\n } else {\\n uint256 j = i - tokensInNew.length;\\n tokens[i] = tokensInOld[j];\\n }\\n }\\n\\n return tokens;\\n }\\n\\n /// @notice Get balance of a token owned by user\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function userTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n return\\n LibShares.sharesToToken(\\n shares[_user][_token],\\n totalShares[_token],\\n totalBalance\\n );\\n }\\n\\n /// @notice Get balance of a token owned by user across treasuries\\n /// @param _user User to get balance from\\n /// @param _token Token to check balance of\\n function totalUserTokenBalance(address _user, address _token)\\n public\\n view\\n override\\n returns (uint256)\\n {\\n uint256 balanceInNew = userTokenBalance(_user, _token);\\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\\n\\n uint256 balance = balanceInNew + balanceInOld;\\n\\n return balance;\\n }\\n\\n function _creditUser(\\n address _user,\\n address _token,\\n uint256 _amount,\\n uint256 _totalBalance\\n ) internal {\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCredit = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n _totalBalance\\n );\\n\\n if (sharesTotal == 0)\\n require(\\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Require MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n require(sharesToCredit > 0, \\\"TaskTreasury: Zero shares to credit\\\");\\n\\n shares[_user][_token] += sharesToCredit;\\n totalShares[_token] = sharesTotal + sharesToCredit;\\n\\n _tokens[_user].add(_token);\\n }\\n\\n function _deductUser(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesTotal = totalShares[_token];\\n uint256 sharesToCharge = LibShares.tokenToShares(\\n _token,\\n _amount,\\n sharesTotal,\\n totalBalance\\n );\\n\\n require(\\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\\n \\\"TaskTreasury: Below MIN_SHARES_IN_TREASURY\\\"\\n );\\n\\n uint256 sharesOfUser = shares[_user][_token];\\n\\n shares[_user][_token] = sharesOfUser - sharesToCharge;\\n totalShares[_token] = sharesTotal - sharesToCharge;\\n\\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\\n }\\n\\n function _pay(\\n address _user,\\n address _token,\\n uint256 _amount\\n ) internal {\\n address admin = _proxyAdmin();\\n require(_user != admin, \\\"TaskTreasury: No proxy admin\\\");\\n\\n uint256 totalBalance = LibShares.contractBalance(_token);\\n uint256 sharesToPay = LibShares.tokenToShares(\\n _token,\\n _amount,\\n totalShares[_token],\\n totalBalance\\n );\\n\\n require(\\n shares[_user][_token] >= sharesToPay,\\n \\\"TaskTreasury: Not enough funds\\\"\\n );\\n shares[_user][_token] -= sharesToPay;\\n shares[admin][_token] += sharesToPay;\\n }\\n}\\n\",\"keccak256\":\"0x5e02f6632abcc9db021bcb07d1f8f9acb048b351c3c1d77dc173df173f783f28\",\"license\":\"UNLICENSED\"},\"contracts/vendor/gelato/FGelato.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.12;\\n\\nimport {\\n SafeERC20,\\n IERC20\\n} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\\n\\n// solhint-disable private-vars-leading-underscore\\n// solhint-disable func-visibility\\nfunction _transfer(\\n address payable _to,\\n address _paymentToken,\\n uint256 _amount\\n) {\\n if (_paymentToken == ETH) {\\n (bool success, ) = _to.call{value: _amount}(\\\"\\\");\\n require(success, \\\"_transfer: ETH transfer failed\\\");\\n } else {\\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\\n }\\n}\\n\",\"keccak256\":\"0xecf150c4e9030703ac85cd5192fb98eca2e68a8df00ca50efd99fc8813cfb4a2\",\"license\":\"UNLICENSED\"},\"contracts/vendor/proxy/EIP173/Proxied.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nabstract contract Proxied {\\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\\n /// It also allows these functions to be called inside a contructor\\n /// even if the contract is meant to be used without proxy\\n modifier proxied() {\\n address proxyAdminAddress = _proxyAdmin();\\n // With hardhat-deploy proxies\\n // the proxyAdminAddress is zero only for the implementation contract\\n // if the implementation contract want to be used as a standalone/immutable contract\\n // it simply has to execute the `proxied` function\\n // This ensure the proxyAdminAddress is never zero post deployment\\n // And allow you to keep the same code for both proxied contract and immutable contract\\n if (proxyAdminAddress == address(0)) {\\n // ensure can not be called twice when used outside of proxy : no admin\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\\n )\\n }\\n } else {\\n require(msg.sender == proxyAdminAddress);\\n }\\n _;\\n }\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n}\\n\",\"keccak256\":\"0x428ced1961d42c505a3e49d90498f92f4b0df8537e5ffa59f14ba375d99150a1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003c2d38038062003c2d8339818101604052810190620000379190620000f0565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000122565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a48262000077565b9050919050565b6000620000b88262000097565b9050919050565b620000ca81620000ab565b8114620000d657600080fd5b50565b600081519050620000ea81620000bf565b92915050565b60006020828403121562000109576200010862000072565b5b60006200011984828501620000d9565b91505092915050565b608051613acc6200016160003960008181610aa501528181610b4a01528181610be701528181610d610152818161117901526111ae0152613acc6000f3fe6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "deployedBytecode": "0x6080604052600436106100f75760003560e01c8063a3f1233e1161008a578063c1461d5711610059578063c1461d5714610378578063cf0ef51614610394578063d147adb9146103bf578063fe4b84df146103fc5761011d565b8063a3f1233e14610298578063b0da8d0b146102c1578063b47064c8146102fe578063bf6b874e1461033b5761011d565b80632bf30a0e116100c65780632bf30a0e146101ca578063550dddeb146102075780635dfad06a146102305780637df446471461025b5761011d565b806301f59d161461012257806303c845961461014d5780630a9b1803146101785780631c20fadd146101a15761011d565b3661011d5761011b3373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee34610425565b005b600080fd5b34801561012e57600080fd5b506101376106d4565b6040516101449190612619565b60405180910390f35b34801561015957600080fd5b506101626106da565b60405161016f9190612619565b60405180910390f35b34801561018457600080fd5b5061019f600480360381019061019a91906126de565b6106e3565b005b3480156101ad57600080fd5b506101c860048036038101906101c39190612788565b6107e0565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906127db565b6108cc565b6040516101fe91906128c6565b60405180910390f35b34801561021357600080fd5b5061022e600480360381019061022991906128e8565b61091c565b005b34801561023c57600080fd5b506102456109c8565b60405161025291906128c6565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190612915565b6109d9565b60405161028f9190612619565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190612955565b6109fe565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906127db565b610d10565b6040516102f591906128c6565b60405180910390f35b34801561030a57600080fd5b5061032560048036038101906103209190612915565b611082565b6040516103329190612619565b60405180910390f35b34801561034757600080fd5b50610362600480360381019061035d91906127db565b61115f565b60405161036f9190612619565b60405180910390f35b610392600480360381019061038d9190612955565b610425565b005b3480156103a057600080fd5b506103a9611177565b6040516103b69190612a07565b60405180910390f35b3480156103cb57600080fd5b506103e660048036038101906103e19190612915565b61119b565b6040516103f39190612619565b60405180910390f35b34801561040857600080fd5b50610423600480360381019061041e91906128e8565b611266565b005b6002600154141561046b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161046290612a7f565b60405180910390fd5b600260018190555060008073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156104c657349150610649565b60003414610509576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050090612aeb565b60405180910390fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105499190612b1a565b602060405180830381865afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612b4a565b90506105b93330878573ffffffffffffffffffffffffffffffffffffffff1661135a909392919063ffffffff16565b60008273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016105f49190612b1a565b602060405180830381865afa158015610611573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106359190612b4a565b905081816106439190612ba6565b94505050505b81610653856113e3565b61065d9190612ba6565b905061066b858584846114b7565b818473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167ff0d0e99cae184d0187b093b48894117462462379674a6e11d89c3fbb618e96b060405160405180910390a4505060018081905550505050565b60335481565b64e8d4a5100081565b6106eb6116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610758576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074f90612c26565b60405180910390fd5b80156107785761077282603761170590919063ffffffff16565b5061078e565b61078c82603761173590919063ffffffff16565b505b8173ffffffffffffffffffffffffffffffffffffffff167f112acfcc345761cf642cf6d7086cc68572679c383746552dcf2f71b26623c158826040516107d49190612c55565b60405180910390a25050565b60026001541415610826576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081d90612a7f565b60405180910390fd5b6002600181905550610839338383611765565b6108448383836119d9565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc322efa58c9cb2c39cfffdac61d35c8643f5cbf13c6a7d0034de2cf18923aff3846040516108b89190612619565b60405180910390a460018081905550505050565b6060610915603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b9050919050565b6109246116dc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098890612c26565b60405180910390fd5b80603381905550807fd4710696fc3761c070b614c80e5020d726828d5f75aa8a6b8287c4194dfe6da260405160405180910390a250565b60606109d46037611ae4565b905090565b6034602052816000526040600020602052806000526040600020600091509150505481565b610a12336037611b0590919063ffffffff16565b610a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a4890612ce2565b60405180910390fd5b600060335414610aa157806033541015610aa0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9790612d4e565b60405180910390fd5b5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c885856040518363ffffffff1660e01b8152600401610afe929190612d6e565b602060405180830381865afa158015610b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3f9190612b4a565b9050808211610bdc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8484876040518463ffffffff1660e01b8152600401610ba593929190612d97565b600060405180830381600087803b158015610bbf57600080fd5b505af1158015610bd3573d6000803e3d6000fd5b50505050610c8c565b6000811115610c75577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636f192acc8483876040518463ffffffff1660e01b8152600401610c4293929190612d97565b600060405180830381600087803b158015610c5c57600080fd5b505af1158015610c70573d6000803e3d6000fd5b505050505b610c8b84848385610c869190612ba6565b611b35565b5b8273ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fe06da4bed68570a3adccb02d0aed523ccc1dd372f85808168917d1c4a7e78acb8533604051610d02929190612dce565b60405180910390a450505050565b60606000610d5b603660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611ae4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632bf30a0e856040518263ffffffff1660e01b8152600401610db89190612b1a565b600060405180830381865afa158015610dd5573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610dfe9190612f65565b90506000805b8251811015610f0657610e78838281518110610e2357610e22612fae565b5b6020026020010151603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b0590919063ffffffff16565b610ef357828181518110610e8f57610e8e612fae565b5b6020026020010151838381518110610eaa57610ea9612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508180610eef90612fdd565b9250505b8080610efe90612fdd565b915050610e04565b506000818451610f169190613026565b905060008167ffffffffffffffff811115610f3457610f33612e0d565b5b604051908082528060200260200182016040528015610f625781602001602082028036833780820191505090505b50905060005b82811015611074578551811015610fe657858181518110610f8c57610f8b612fae565b5b6020026020010151828281518110610fa757610fa6612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611061565b6000865182610ff59190612ba6565b905085818151811061100a57611009612fae565b5b602002602001015183838151811061102557611024612fae565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505b808061106c90612fdd565b915050610f68565b508095505050505050919050565b60008061108e836113e3565b9050611156603460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054603560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205483611df9565b91505092915050565b60356020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806111a88484611082565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b47064c886866040518363ffffffff1660e01b8152600401611207929190612d6e565b602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112489190612b4a565b9050600081836112589190613026565b905080935050505092915050565b600060019054906101000a900460ff1661128e5760008054906101000a900460ff1615611297565b611296611e3e565b5b6112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906130ee565b60405180910390fd5b60008060019054906101000a900460ff161590508015611326576001600060016101000a81548160ff02191690831515021790555060016000806101000a81548160ff0219169083151502179055505b81603381905550611335611e4f565b80156113565760008060016101000a81548160ff0219169083151502179055505b5050565b6113dd846323b872dd60e01b85858560405160240161137b9392919061310e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b50505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611435574790506114b2565b8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161146e9190612b1a565b602060405180830381865afa15801561148b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114af9190612b4a565b90505b919050565b6000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600061150985858486611f6f565b9050600082141561155d5764e8d4a5100081101561155c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611553906131b7565b60405180910390fd5b5b600081116115a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159790613249565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461162c9190613026565b92505081905550808261163f9190613026565b603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506116d385603660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061170590919063ffffffff16565b50505050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b600061172d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611fd0565b905092915050565b600061175d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612040565b905092915050565b6000611770836113e3565b90506000603560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060006117c485858486611f6f565b905064e8d4a5100081836117d89190612ba6565b1015611819576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611810906132db565b60405180910390fd5b6000603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081816118a69190612ba6565b603460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081836119329190612ba6565b603560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550818114156119d0576119ce86603660008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061173590919063ffffffff16565b505b50505050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611ad35760008373ffffffffffffffffffffffffffffffffffffffff1682604051611a479061332c565b60006040518083038185875af1925050503d8060008114611a84576040519150601f19603f3d011682016040523d82523d6000602084013e611a89565b606091505b5050905080611acd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ac49061338d565b60405180910390fd5b50611adf565b611ade828483612154565b5b505050565b60606000611af4836000016121da565b905060608190508092505050919050565b6000611b2d836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612236565b905092915050565b6000611b3f6116dc565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611bb0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba7906133f9565b60405180910390fd5b6000611bbb846113e3565b90506000611c0a8585603560008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205485611f6f565b905080603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015611ccb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc290613465565b60405180910390fd5b80603460008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d579190612ba6565b9250508190555080603460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611dea9190613026565b92505081905550505050505050565b6000806000841480611e0b5750600083145b15611e195760009050611e33565b838386611e269190613485565b611e30919061350e565b90505b809150509392505050565b6000611e4930612259565b15905090565b600060019054906101000a900460ff16611e9e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e95906135b1565b60405180910390fd5b611ea661226c565b565b6000611f0a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166122c49092919063ffffffff16565b9050600081511115611f6a5780806020019051810190611f2a91906135e6565b611f69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6090613685565b60405180910390fd5b5b505050565b6000806000611f7e87876122dc565b90506000611f8c88866122dc565b90506000861480611f9d5750600085145b15611faa57819250611fc2565b611fbf8683611fb99190613485565b82612404565b92505b829350505050949350505050565b6000611fdc8383612236565b61203557826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061203a565b600090505b92915050565b600080836001016000848152602001908152602001600020549050600081146121485760006001826120729190612ba6565b905060006001866000018054905061208a9190612ba6565b90508181146120f95760008660000182815481106120ab576120aa612fae565b5b90600052602060002001549050808760000184815481106120cf576120ce612fae565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b8560000180548061210d5761210c6136a5565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061214e565b60009150505b92915050565b6121d58363a9059cbb60e01b84846040516024016121739291906136d4565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050611ea8565b505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561222a57602002820191906000526020600020905b815481526020019060010190808311612216575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600080823b905060008111915050919050565b600060019054906101000a900460ff166122bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122b2906135b1565b60405180910390fd5b60018081905550565b60606122d38484600085612462565b90509392505050565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561232e578190506123fe565b60008373ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801561237b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239f9190612b4a565b905060128110156123d6578060126123b79190612ba6565b600a6123c39190613830565b836123ce9190613485565b9150506123fe565b6012816123e39190612ba6565b600a6123ef9190613830565b836123fa919061350e565b9150505b92915050565b6000808284612413919061387b565b905060008082141561243257838561242b919061350e565b9050612457565b838483876124409190612ba6565b61244a9190613026565b612454919061350e565b90505b809250505092915050565b6060824710156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161249e9061391e565b60405180910390fd5b6124b085612576565b6124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69061398a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125189190613a19565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a828286612599565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606083156125a9578290506125f9565b6000835111156125bc5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f09190613a74565b60405180910390fd5b9392505050565b6000819050919050565b61261381612600565b82525050565b600060208201905061262e600083018461260a565b92915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061267382612648565b9050919050565b61268381612668565b811461268e57600080fd5b50565b6000813590506126a08161267a565b92915050565b60008115159050919050565b6126bb816126a6565b81146126c657600080fd5b50565b6000813590506126d8816126b2565b92915050565b600080604083850312156126f5576126f461263e565b5b600061270385828601612691565b9250506020612714858286016126c9565b9150509250929050565b600061272982612648565b9050919050565b6127398161271e565b811461274457600080fd5b50565b60008135905061275681612730565b92915050565b61276581612600565b811461277057600080fd5b50565b6000813590506127828161275c565b92915050565b6000806000606084860312156127a1576127a061263e565b5b60006127af86828701612747565b93505060206127c086828701612691565b92505060406127d186828701612773565b9150509250925092565b6000602082840312156127f1576127f061263e565b5b60006127ff84828501612691565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61283d81612668565b82525050565b600061284f8383612834565b60208301905092915050565b6000602082019050919050565b600061287382612808565b61287d8185612813565b935061288883612824565b8060005b838110156128b95781516128a08882612843565b97506128ab8361285b565b92505060018101905061288c565b5085935050505092915050565b600060208201905081810360008301526128e08184612868565b905092915050565b6000602082840312156128fe576128fd61263e565b5b600061290c84828501612773565b91505092915050565b6000806040838503121561292c5761292b61263e565b5b600061293a85828601612691565b925050602061294b85828601612691565b9150509250929050565b60008060006060848603121561296e5761296d61263e565b5b600061297c86828701612691565b935050602061298d86828701612691565b925050604061299e86828701612773565b9150509250925092565b6000819050919050565b60006129cd6129c86129c384612648565b6129a8565b612648565b9050919050565b60006129df826129b2565b9050919050565b60006129f1826129d4565b9050919050565b612a01816129e6565b82525050565b6000602082019050612a1c60008301846129f8565b92915050565b600082825260208201905092915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000612a69601f83612a22565b9150612a7482612a33565b602082019050919050565b60006020820190508181036000830152612a9881612a5c565b9050919050565b7f5461736b54726561737572793a204e6f20455448000000000000000000000000600082015250565b6000612ad5601483612a22565b9150612ae082612a9f565b602082019050919050565b60006020820190508181036000830152612b0481612ac8565b9050919050565b612b1481612668565b82525050565b6000602082019050612b2f6000830184612b0b565b92915050565b600081519050612b448161275c565b92915050565b600060208284031215612b6057612b5f61263e565b5b6000612b6e84828501612b35565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612bb182612600565b9150612bbc83612600565b925082821015612bcf57612bce612b77565b5b828203905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000612c10600e83612a22565b9150612c1b82612bda565b602082019050919050565b60006020820190508181036000830152612c3f81612c03565b9050919050565b612c4f816126a6565b82525050565b6000602082019050612c6a6000830184612c46565b92915050565b7f5461736b54726561737572793a206f6e6c7957686974656c697374656453657260008201527f7669636573000000000000000000000000000000000000000000000000000000602082015250565b6000612ccc602583612a22565b9150612cd782612c70565b604082019050919050565b60006020820190508181036000830152612cfb81612cbf565b9050919050565b7f5461736b54726561737572793a204f7665726368617267656400000000000000600082015250565b6000612d38601983612a22565b9150612d4382612d02565b602082019050919050565b60006020820190508181036000830152612d6781612d2b565b9050919050565b6000604082019050612d836000830185612b0b565b612d906020830184612b0b565b9392505050565b6000606082019050612dac6000830186612b0b565b612db9602083018561260a565b612dc66040830184612b0b565b949350505050565b6000604082019050612de3600083018561260a565b612df06020830184612b0b565b9392505050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e4582612dfc565b810181811067ffffffffffffffff82111715612e6457612e63612e0d565b5b80604052505050565b6000612e77612634565b9050612e838282612e3c565b919050565b600067ffffffffffffffff821115612ea357612ea2612e0d565b5b602082029050602081019050919050565b600080fd5b600081519050612ec88161267a565b92915050565b6000612ee1612edc84612e88565b612e6d565b90508083825260208201905060208402830185811115612f0457612f03612eb4565b5b835b81811015612f2d5780612f198882612eb9565b845260208401935050602081019050612f06565b5050509392505050565b600082601f830112612f4c57612f4b612df7565b5b8151612f5c848260208601612ece565b91505092915050565b600060208284031215612f7b57612f7a61263e565b5b600082015167ffffffffffffffff811115612f9957612f98612643565b5b612fa584828501612f37565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000612fe882612600565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561301b5761301a612b77565b5b600182019050919050565b600061303182612600565b915061303c83612600565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561307157613070612b77565b5b828201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006130d8602e83612a22565b91506130e38261307c565b604082019050919050565b60006020820190508181036000830152613107816130cb565b9050919050565b60006060820190506131236000830186612b0b565b6131306020830185612b0b565b61313d604083018461260a565b949350505050565b7f5461736b54726561737572793a2052657175697265204d494e5f53484152455360008201527f5f494e5f54524541535552590000000000000000000000000000000000000000602082015250565b60006131a1602c83612a22565b91506131ac82613145565b604082019050919050565b600060208201905081810360008301526131d081613194565b9050919050565b7f5461736b54726561737572793a205a65726f2073686172657320746f2063726560008201527f6469740000000000000000000000000000000000000000000000000000000000602082015250565b6000613233602383612a22565b915061323e826131d7565b604082019050919050565b6000602082019050818103600083015261326281613226565b9050919050565b7f5461736b54726561737572793a2042656c6f77204d494e5f5348415245535f4960008201527f4e5f545245415355525900000000000000000000000000000000000000000000602082015250565b60006132c5602a83612a22565b91506132d082613269565b604082019050919050565b600060208201905081810360008301526132f4816132b8565b9050919050565b600081905092915050565b50565b60006133166000836132fb565b915061332182613306565b600082019050919050565b600061333782613309565b9150819050919050565b7f5f7472616e736665723a20455448207472616e73666572206661696c65640000600082015250565b6000613377601e83612a22565b915061338282613341565b602082019050919050565b600060208201905081810360008301526133a68161336a565b9050919050565b7f5461736b54726561737572793a204e6f2070726f78792061646d696e00000000600082015250565b60006133e3601c83612a22565b91506133ee826133ad565b602082019050919050565b60006020820190508181036000830152613412816133d6565b9050919050565b7f5461736b54726561737572793a204e6f7420656e6f7567682066756e64730000600082015250565b600061344f601e83612a22565b915061345a82613419565b602082019050919050565b6000602082019050818103600083015261347e81613442565b9050919050565b600061349082612600565b915061349b83612600565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156134d4576134d3612b77565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061351982612600565b915061352483612600565b925082613534576135336134df565b5b828204905092915050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b600061359b602b83612a22565b91506135a68261353f565b604082019050919050565b600060208201905081810360008301526135ca8161358e565b9050919050565b6000815190506135e0816126b2565b92915050565b6000602082840312156135fc576135fb61263e565b5b600061360a848285016135d1565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b600061366f602a83612a22565b915061367a82613613565b604082019050919050565b6000602082019050818103600083015261369e81613662565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006040820190506136e96000830185612b0b565b6136f6602083018461260a565b9392505050565b60008160011c9050919050565b6000808291508390505b6001851115613754578086048111156137305761372f612b77565b5b600185161561373f5780820291505b808102905061374d856136fd565b9450613714565b94509492505050565b60008261376d5760019050613829565b8161377b5760009050613829565b8160018114613791576002811461379b576137ca565b6001915050613829565b60ff8411156137ad576137ac612b77565b5b8360020a9150848211156137c4576137c3612b77565b5b50613829565b5060208310610133831016604e8410600b84101617156137ff5782820a9050838111156137fa576137f9612b77565b5b613829565b61380c848484600161370a565b9250905081840481111561382357613822612b77565b5b81810290505b9392505050565b600061383b82612600565b915061384683612600565b92506138737fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461375d565b905092915050565b600061388682612600565b915061389183612600565b9250826138a1576138a06134df565b5b828206905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b6000613908602683612a22565b9150613913826138ac565b604082019050919050565b60006020820190508181036000830152613937816138fb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613974601d83612a22565b915061397f8261393e565b602082019050919050565b600060208201905081810360008301526139a381613967565b9050919050565b600081519050919050565b60005b838110156139d35780820151818401526020810190506139b8565b838111156139e2576000848401525b50505050565b60006139f3826139aa565b6139fd81856132fb565b9350613a0d8185602086016139b5565b80840191505092915050565b6000613a2582846139e8565b915081905092915050565b600081519050919050565b6000613a4682613a30565b613a508185612a22565b9350613a608185602086016139b5565b613a6981612dfc565b840191505092915050565b60006020820190508181036000830152613a8e8184613a3b565b90509291505056fea264697066735822122041f45bcee684845ffa450d88eb0e84a5b7e307c0a356f2d4829ce349fa7145d664736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": { + "depositFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + }, + "getCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "getTotalCreditTokensByUser(address)": { + "params": { + "_user": "User to get the balances from" + } + }, + "totalUserTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "updateMaxFee(uint256)": { + "params": { + "_newMaxFee": "New Max Fee to charge" + } + }, + "updateWhitelistedService(address,bool)": { + "params": { + "_add": "Add to whitelist if true, else remove from whitelist", + "_service": "Service to add or remove from whitelist" + } + }, + "useFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be deducted", + "_token": "Token to be used for payment by users", + "_user": "Address of user whose balance will be deducted" + } + }, + "userTokenBalance(address,address)": { + "params": { + "_token": "Token to check balance of", + "_user": "User to get balance from" + } + }, + "withdrawFunds(address,address,uint256)": { + "params": { + "_amount": "Amount to be credited", + "_receiver": "Address receiving the credits", + "_token": "Token to be credited, use \"0xeeee....\" for ETH" + } + } + }, + "stateVariables": { + "_tokens": { + "details": "tracks the tokens deposited by users" + }, + "shares": { + "details": "tracks token shares of users" + }, + "totalShares": { + "details": "tracks total shares of tokens" + } + }, + "version": 1 + }, + "userdoc": { + "events": { + "FundsDeposited(address,address,uint256)": { + "notice": "Events ///" + } + }, + "kind": "user", + "methods": { + "depositFunds(address,address,uint256)": { + "notice": "Function to deposit Funds which will be used to execute transactions on various services" + }, + "getCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user." + }, + "getTotalCreditTokensByUser(address)": { + "notice": "Helper func to get all deposited tokens by a user across treasuries." + }, + "getWhitelistedServices()": { + "notice": "Get list of services that can call useFunds." + }, + "totalUserTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user across treasuries" + }, + "updateMaxFee(uint256)": { + "notice": "Change maxFee charged by Gelato (only relevant on Layer2s)" + }, + "updateWhitelistedService(address,bool)": { + "notice": "Add or remove service that can call useFunds. Gelato Governance" + }, + "useFunds(address,address,uint256)": { + "notice": "Function called by whitelisted services to handle payments, e.g. Gelato Ops" + }, + "userTokenBalance(address,address)": { + "notice": "Get balance of a token owned by user" + }, + "withdrawFunds(address,address,uint256)": { + "notice": "Function to withdraw Funds back to the _receiver" + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 6, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 9, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 87, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_status", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 130, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "__gap", + "offset": 0, + "slot": "2", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 4441, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "maxFee", + "offset": 0, + "slot": "51", + "type": "t_uint256" + }, + { + "astId": 4448, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "shares", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4453, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "totalShares", + "offset": 0, + "slot": "53", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4459, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_tokens", + "offset": 0, + "slot": "54", + "type": "t_mapping(t_address,t_struct(AddressSet)1540_storage)" + }, + { + "astId": 4462, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_whitelistedServices", + "offset": 0, + "slot": "55", + "type": "t_struct(AddressSet)1540_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_bytes32)dyn_storage": { + "base": "t_bytes32", + "encoding": "dynamic_array", + "label": "bytes32[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_struct(AddressSet)1540_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)1540_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)1540_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 1539, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)1239_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)1239_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 1234, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 1238, + "contract": "contracts/taskTreasury/TaskTreasuryUpgradable.sol:TaskTreasuryUpgradable", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/ropsten/TaskTreasuryUpgradable_Proxy.json b/deployments/ropsten/TaskTreasuryUpgradable_Proxy.json new file mode 100644 index 00000000..9945961f --- /dev/null +++ b/deployments/ropsten/TaskTreasuryUpgradable_Proxy.json @@ -0,0 +1,217 @@ +{ + "address": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "implementationAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "ownerAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "ProxyAdminTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousImplementation", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "ProxyImplementationUpdated", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "proxyAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "id", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "transferProxyAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "receipt": { + "to": null, + "from": "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "contractAddress": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "transactionIndex": 0, + "gasUsed": "762902", + "logsBloom": "0x00100000000020000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000200000000000000000084000000000000001000020000000000000000000000000010000000000000000000000000000020080000000000000000000400000000000002000000000000010000000000000000", + "blockHash": "0xf205ec1f0ab0281342107ef30077e8b0aacab4d2537a25690b5cc81e3783df19", + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 12170551, + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "address": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "topics": [ + "0x5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b7379068296", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000f278d2e1c82fe85e03dd97c46f22e860f90d564" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xf205ec1f0ab0281342107ef30077e8b0aacab4d2537a25690b5cc81e3783df19" + }, + { + "transactionIndex": 0, + "blockNumber": 12170551, + "transactionHash": "0xae0a78e241f60b2efc30eff2b87ddf78e9740820c0ae6e7dea9b127c3e528ff9", + "address": "0xc12DfF74311B73d495D43b9959Eb6ce1E407F380", + "topics": [ + "0xdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec29", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cdf41a135c65d0013393b3793f92b4faf31032d0" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xf205ec1f0ab0281342107ef30077e8b0aacab4d2537a25690b5cc81e3783df19" + } + ], + "blockNumber": 12170551, + "cumulativeGasUsed": "762902", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0f278d2E1C82fE85e03DD97c46F22e860F90D564", + "0xCDf41a135C65d0013393B3793F92b4FAF31032d0", + "0xfe4b84df0000000000000000000000000000000000000000000000000000000000000000" + ], + "solcInputHash": "07324167f4bf468b271334a7271a4559", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"implementationAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ownerAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"ProxyAdminTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousImplementation\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"ProxyImplementationUpdated\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"proxyAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"id\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"transferProxyAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Proxy implementing EIP173 for ownership management that accept ETH via receive\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":\"EIP173ProxyWithCustomReceive\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/vendor/proxy/EIP173/EIP173Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./Proxy.sol\\\";\\n\\ninterface ERC165 {\\n function supportsInterface(bytes4 id) external view returns (bool);\\n}\\n\\n///@notice Proxy implementing EIP173 for ownership management\\ncontract EIP173Proxy is Proxy {\\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\\n\\n event ProxyAdminTransferred(\\n address indexed previousAdmin,\\n address indexed newAdmin\\n );\\n\\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\\n\\n constructor(\\n address implementationAddress,\\n address adminAddress,\\n bytes memory data\\n ) payable {\\n _setImplementation(implementationAddress, data);\\n _setProxyAdmin(adminAddress);\\n }\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n function proxyAdmin() external view returns (address) {\\n return _proxyAdmin();\\n }\\n\\n function supportsInterface(bytes4 id) external view returns (bool) {\\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\\n return true;\\n }\\n if (id == 0xFFFFFFFF) {\\n return false;\\n }\\n\\n ERC165 implementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n implementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\\n // In practise this is unlikely to be an issue.\\n try implementation.supportsInterface(id) returns (bool support) {\\n return support;\\n } catch {\\n return false;\\n }\\n }\\n\\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\\n _setProxyAdmin(newAdmin);\\n }\\n\\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\\n _setImplementation(newImplementation, \\\"\\\");\\n }\\n\\n function upgradeToAndCall(address newImplementation, bytes calldata data)\\n external\\n payable\\n onlyProxyAdmin\\n {\\n _setImplementation(newImplementation, data);\\n }\\n\\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\\n\\n modifier onlyProxyAdmin() {\\n require(msg.sender == _proxyAdmin(), \\\"NOT_AUTHORIZED\\\");\\n _;\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _proxyAdmin() internal view returns (address adminAddress) {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n adminAddress := sload(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\\n )\\n }\\n }\\n\\n function _setProxyAdmin(address newAdmin) internal {\\n address previousAdmin = _proxyAdmin();\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\\n newAdmin\\n )\\n }\\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\\n }\\n}\\n\",\"keccak256\":\"0x09fe40909bb79ccee2a7a2aa7b23ec9447efb70b1716bc13027dd239f9d438c0\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./EIP173Proxy.sol\\\";\\n\\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\\n constructor(\\n address implementationAddress,\\n address ownerAddress,\\n bytes memory data\\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\\n\\n receive() external payable override {\\n _fallback();\\n }\\n}\\n\",\"keccak256\":\"0xc9b83d1648483977267dfaf47a2bdc84f245e2197646120533c001f4d4c2f976\",\"license\":\"GPL-3.0\"},\"contracts/vendor/proxy/EIP173/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n// EIP-1967\\nabstract contract Proxy {\\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\\n\\n event ProxyImplementationUpdated(\\n address indexed previousImplementation,\\n address indexed newImplementation\\n );\\n\\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\\n\\n // prettier-ignore\\n receive() external payable virtual {\\n revert(\\\"ETHER_REJECTED\\\"); // explicit reject by default\\n }\\n\\n fallback() external payable {\\n _fallback();\\n }\\n\\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\\n\\n function _fallback() internal {\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n let implementationAddress := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n calldatacopy(0x0, 0x0, calldatasize())\\n let success := delegatecall(\\n gas(),\\n implementationAddress,\\n 0x0,\\n calldatasize(),\\n 0,\\n 0\\n )\\n let retSz := returndatasize()\\n returndatacopy(0, 0, retSz)\\n switch success\\n case 0 {\\n revert(0, retSz)\\n }\\n default {\\n return(0, retSz)\\n }\\n }\\n }\\n\\n function _setImplementation(address newImplementation, bytes memory data)\\n internal\\n {\\n address previousImplementation;\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n previousImplementation := sload(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\\n )\\n }\\n\\n // solhint-disable-next-line security/no-inline-assembly\\n assembly {\\n sstore(\\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\\n newImplementation\\n )\\n }\\n\\n emit ProxyImplementationUpdated(\\n previousImplementation,\\n newImplementation\\n );\\n\\n if (data.length > 0) {\\n (bool success, ) = newImplementation.delegatecall(data);\\n if (!success) {\\n assembly {\\n // This assembly ensure the revert contains the exact string data\\n let returnDataSize := returndatasize()\\n returndatacopy(0, 0, returnDataSize)\\n revert(0, returnDataSize)\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xb5e3e1c4cab8a5e3bd968f51c201a11e651f62b47aa78a4e3e0b7508be268d35\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405260405162000fed38038062000fed833981810160405281019062000029919062000450565b8282826200003e83826200005b60201b60201c565b6200004f826200019060201b60201c565b50505050505062000531565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156200018b5760008373ffffffffffffffffffffffffffffffffffffffff168360405162000132919062000518565b600060405180830381855af49150503d80600081146200016f576040519150601f19603f3d011682016040523d82523d6000602084013e62000174565b606091505b505090508062000189573d806000803e806000fd5b505b505050565b6000620001a26200022560201b60201c565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200028f8262000262565b9050919050565b620002a18162000282565b8114620002ad57600080fd5b50565b600081519050620002c18162000296565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200031c82620002d1565b810181811067ffffffffffffffff821117156200033e576200033d620002e2565b5b80604052505050565b6000620003536200024e565b905062000361828262000311565b919050565b600067ffffffffffffffff821115620003845762000383620002e2565b5b6200038f82620002d1565b9050602081019050919050565b60005b83811015620003bc5780820151818401526020810190506200039f565b83811115620003cc576000848401525b50505050565b6000620003e9620003e38462000366565b62000347565b905082815260208101848484011115620004085762000407620002cc565b5b620004158482856200039c565b509392505050565b600082601f830112620004355762000434620002c7565b5b815162000447848260208601620003d2565b91505092915050565b6000806000606084860312156200046c576200046b62000258565b5b60006200047c86828701620002b0565b93505060206200048f86828701620002b0565b925050604084015167ffffffffffffffff811115620004b357620004b26200025d565b5b620004c1868287016200041d565b9150509250925092565b600081519050919050565b600081905092915050565b6000620004ee82620004cb565b620004fa8185620004d6565b93506200050c8185602086016200039c565b80840191505092915050565b6000620005268284620004e1565b915081905092915050565b610aac80620005416000396000f3fe60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "deployedBytecode": "0x60806040526004361061004e5760003560e01c806301ffc9a7146100675780633659cfe6146100a45780633e47158c146100cd5780634f1ef286146100f85780638356ca4f146101145761005d565b3661005d5761005b61013d565b005b61006561013d565b005b34801561007357600080fd5b5061008e60048036038101906100899190610708565b610186565b60405161009b9190610750565b60405180910390f35b3480156100b057600080fd5b506100cb60048036038101906100c691906107c9565b6102d8565b005b3480156100d957600080fd5b506100e2610369565b6040516100ef9190610805565b60405180910390f35b610112600480360381019061010d9190610885565b610378565b005b34801561012057600080fd5b5061013b600480360381019061013691906107c9565b610440565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc543660008037600080366000845af43d806000803e816000811461018157816000f35b816000fd5b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806101e15750637f5828d060e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b156101ef57600190506102d3565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561022657600090506102d3565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490508073ffffffffffffffffffffffffffffffffffffffff166301ffc9a7846040518263ffffffff1660e01b815260040161028591906108f4565b602060405180830381865afa9250505080156102bf57506040513d601f19601f820116820180604052508101906102bc919061093b565b60015b6102cd5760009150506102d3565b80925050505b919050565b6102e06104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461034d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610344906109c5565b60405180910390fd5b61036681604051806020016040528060008152506104ea565b50565b60006103736104c1565b905090565b6103806104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103e4906109c5565b60405180910390fd5b61043b8383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104ea565b505050565b6104486104c1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104ac906109c5565b60405180910390fd5b6104be81610619565b50565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc549050827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc558273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f5570d70a002632a7b0b3c9304cc89efb62d8da9eca0dbd7752c83b737906829660405160405180910390a36000825111156106145760008373ffffffffffffffffffffffffffffffffffffffff16836040516105be9190610a5f565b600060405180830381855af49150503d80600081146105f9576040519150601f19603f3d011682016040523d82523d6000602084013e6105fe565b606091505b5050905080610612573d806000803e806000fd5b505b505050565b60006106236104c1565b9050817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103558173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167fdf435d422321da6b195902d70fc417c06a32f88379c20dd8f2a8da07088cec2960405160405180910390a35050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6106e5816106b0565b81146106f057600080fd5b50565b600081359050610702816106dc565b92915050565b60006020828403121561071e5761071d6106a6565b5b600061072c848285016106f3565b91505092915050565b60008115159050919050565b61074a81610735565b82525050565b60006020820190506107656000830184610741565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006107968261076b565b9050919050565b6107a68161078b565b81146107b157600080fd5b50565b6000813590506107c38161079d565b92915050565b6000602082840312156107df576107de6106a6565b5b60006107ed848285016107b4565b91505092915050565b6107ff8161078b565b82525050565b600060208201905061081a60008301846107f6565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261084557610844610820565b5b8235905067ffffffffffffffff81111561086257610861610825565b5b60208301915083600182028301111561087e5761087d61082a565b5b9250929050565b60008060006040848603121561089e5761089d6106a6565b5b60006108ac868287016107b4565b935050602084013567ffffffffffffffff8111156108cd576108cc6106ab565b5b6108d98682870161082f565b92509250509250925092565b6108ee816106b0565b82525050565b600060208201905061090960008301846108e5565b92915050565b61091881610735565b811461092357600080fd5b50565b6000815190506109358161090f565b92915050565b600060208284031215610951576109506106a6565b5b600061095f84828501610926565b91505092915050565b600082825260208201905092915050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b60006109af600e83610968565b91506109ba82610979565b602082019050919050565b600060208201905081810360008301526109de816109a2565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015610a195780820151818401526020810190506109fe565b83811115610a28576000848401525b50505050565b6000610a39826109e5565b610a4381856109f0565b9350610a538185602086016109fb565b80840191505092915050565b6000610a6b8284610a2e565b91508190509291505056fea26469706673582212201c02f9868bea1f8e7392ef8bead12df2b877f9987cd7b4eafcdf405b99085bae64736f6c634300080c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "Proxy implementing EIP173 for ownership management that accept ETH via receive", + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} diff --git a/deployments/ropsten/solcInputs/07324167f4bf468b271334a7271a4559.json b/deployments/ropsten/solcInputs/07324167f4bf468b271334a7271a4559.json new file mode 100644 index 00000000..1ebd18fa --- /dev/null +++ b/deployments/ropsten/solcInputs/07324167f4bf468b271334a7271a4559.json @@ -0,0 +1,132 @@ +{ + "language": "Solidity", + "sources": { + "contracts/examples/withoutTreasury/CounterResolverWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolverWithoutTreasury is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/interfaces/IResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IResolver {\n function checker()\n external\n view\n returns (bool canExec, bytes memory execPayload);\n}\n" + }, + "contracts/examples/withTreasury/CounterResolver.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {IResolver} from \"../../interfaces/IResolver.sol\";\n\ninterface ICounter {\n function increaseCount(uint256 amount) external;\n\n function lastExecuted() external view returns (uint256);\n}\n\ncontract CounterResolver is IResolver {\n // solhint-disable var-name-mixedcase\n address public immutable COUNTER;\n\n constructor(address _counter) {\n COUNTER = _counter;\n }\n\n function checker()\n external\n view\n override\n returns (bool canExec, bytes memory execPayload)\n {\n uint256 lastExecuted = ICounter(COUNTER).lastExecuted();\n\n // solhint-disable not-rely-on-time\n canExec = (block.timestamp - lastExecuted) > 180;\n\n execPayload = abi.encodeWithSelector(\n ICounter.increaseCount.selector,\n uint256(100)\n );\n }\n}\n" + }, + "contracts/examples/withoutTreasury/CounterWithoutTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ninterface IOps {\n function getFeeDetails() external view returns (uint256, address);\n}\n\ncontract CounterWithoutTreasury is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable no-empty-blocks\n constructor(address _ops) OpsReady(_ops) {}\n\n receive() external payable {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n\n uint256 fee;\n address feeToken;\n\n (fee, feeToken) = IOps(ops).getFeeDetails();\n\n _transfer(fee, feeToken);\n }\n}\n" + }, + "contracts/vendor/gelato/OpsReady.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ninterface IOps {\n function gelato() external view returns (address payable);\n}\n\nabstract contract OpsReady {\n address public immutable ops;\n address payable public immutable gelato;\n address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n modifier onlyOps() {\n require(msg.sender == ops, \"OpsReady: onlyOps\");\n _;\n }\n\n constructor(address _ops) {\n ops = _ops;\n gelato = IOps(_ops).gelato();\n }\n\n function _transfer(uint256 _amount, address _paymentToken) internal {\n if (_paymentToken == ETH) {\n (bool success, ) = gelato.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/mocks/CounterTimedTask.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../vendor/gelato/OpsReady.sol\";\n\ncontract CounterTimedTask is OpsReady {\n uint256 public count;\n bool public executable;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(executable, \"CounterTimedTask: increaseCount: Not executable\");\n\n count += amount;\n }\n\n function setExecutable(bool _executable) external {\n executable = _executable;\n }\n}\n" + }, + "contracts/examples/withTreasury/Counter.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {OpsReady} from \"../../vendor/gelato/OpsReady.sol\";\n\ncontract Counter is OpsReady {\n uint256 public count;\n uint256 public lastExecuted;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(address payable _ops) OpsReady(_ops) {}\n\n // solhint-disable not-rely-on-time\n function increaseCount(uint256 amount) external onlyOps {\n require(\n ((block.timestamp - lastExecuted) > 180),\n \"Counter: increaseCount: Time not elapsed\"\n );\n\n count += amount;\n lastExecuted = block.timestamp;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n IERC20,\n SafeERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ReentrancyGuardUpgradeable\n} from \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport {\n Initializable\n} from \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {Proxied} from \"../vendor/proxy/EIP173/Proxied.sol\";\nimport {ITaskTreasury} from \"../interfaces/ITaskTreasury.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"../interfaces/ITaskTreasuryUpgradable.sol\";\nimport {LibShares} from \"../libraries/LibShares.sol\";\n\ncontract TaskTreasuryUpgradable is\n ITaskTreasuryUpgradable,\n Proxied,\n Initializable,\n ReentrancyGuardUpgradeable\n{\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n ITaskTreasury public immutable oldTreasury;\n uint256 public constant MIN_SHARES_IN_TREASURY = 1e12;\n uint256 public maxFee;\n\n ///@dev tracks token shares of users\n mapping(address => mapping(address => uint256)) public shares;\n\n ///@dev tracks total shares of tokens\n mapping(address => uint256) public totalShares;\n\n ///@dev tracks the tokens deposited by users\n mapping(address => EnumerableSet.AddressSet) internal _tokens;\n\n EnumerableSet.AddressSet internal _whitelistedServices;\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(ITaskTreasury _oldTreasury) {\n oldTreasury = _oldTreasury;\n }\n\n receive() external payable {\n depositFunds(msg.sender, ETH, msg.value);\n }\n\n function initialize(uint256 _maxFee) external initializer {\n maxFee = _maxFee;\n __ReentrancyGuard_init();\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Gelato Ops\n /// @param _user Address of user whose balance will be deducted\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n function useFunds(\n address _user,\n address _token,\n uint256 _amount\n ) external override onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: Overcharged\");\n\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n if (_amount <= balanceInOld) {\n oldTreasury.useFunds(_token, _amount, _user);\n } else {\n if (balanceInOld > 0)\n oldTreasury.useFunds(_token, balanceInOld, _user);\n\n _pay(_user, _token, _amount - balanceInOld);\n }\n\n emit LogDeductFees(_user, tx.origin, _token, _amount, msg.sender);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function updateMaxFee(uint256 _newMaxFee) external override onlyProxyAdmin {\n maxFee = _newMaxFee;\n\n emit UpdatedMaxFee(_newMaxFee);\n }\n\n /// @notice Add or remove service that can call useFunds. Gelato Governance\n /// @param _service Service to add or remove from whitelist\n /// @param _add Add to whitelist if true, else remove from whitelist\n function updateWhitelistedService(address _service, bool _add)\n external\n override\n onlyProxyAdmin\n {\n if (_add) {\n _whitelistedServices.add(_service);\n } else {\n _whitelistedServices.remove(_service);\n }\n\n emit UpdatedService(_service, _add);\n }\n\n /// @notice Get list of services that can call useFunds.\n function getWhitelistedServices()\n external\n view\n override\n returns (address[] memory)\n {\n return _whitelistedServices.values();\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) public payable override nonReentrant {\n uint256 depositAmount;\n uint256 totalBalance;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n require(msg.value == 0, \"TaskTreasury: No ETH\");\n IERC20 token = IERC20(_token);\n\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n\n depositAmount = postBalance - preBalance;\n }\n\n totalBalance = LibShares.contractBalance(_token) - depositAmount;\n\n _creditUser(_receiver, _token, depositAmount, totalBalance);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) public override nonReentrant {\n _deductUser(msg.sender, _token, _amount);\n\n _transfer(_receiver, _token, _amount);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, _amount);\n }\n\n /// @notice Helper func to get all deposited tokens by a user.\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n return _tokens[_user].values();\n }\n\n /// @notice Helper func to get all deposited tokens by a user across treasuries.\n /// @param _user User to get the balances from\n function getTotalCreditTokensByUser(address _user)\n public\n view\n override\n returns (address[] memory)\n {\n address[] memory tokensInNew = _tokens[_user].values();\n address[] memory tokensInOld = oldTreasury.getCreditTokensByUser(_user);\n\n uint256 tokensInOldOnlyLength;\n for (uint256 i; i < tokensInOld.length; i++) {\n if (!_tokens[_user].contains(tokensInOld[i])) {\n tokensInOld[tokensInOldOnlyLength] = tokensInOld[i];\n tokensInOldOnlyLength++;\n }\n }\n\n uint256 uniqTokensLength = tokensInNew.length + tokensInOldOnlyLength;\n address[] memory tokens = new address[](uniqTokensLength);\n\n for (uint256 i; i < uniqTokensLength; i++) {\n if (i < tokensInNew.length) {\n tokens[i] = tokensInNew[i];\n } else {\n uint256 j = i - tokensInNew.length;\n tokens[i] = tokensInOld[j];\n }\n }\n\n return tokens;\n }\n\n /// @notice Get balance of a token owned by user\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function userTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 totalBalance = LibShares.contractBalance(_token);\n return\n LibShares.sharesToToken(\n shares[_user][_token],\n totalShares[_token],\n totalBalance\n );\n }\n\n /// @notice Get balance of a token owned by user across treasuries\n /// @param _user User to get balance from\n /// @param _token Token to check balance of\n function totalUserTokenBalance(address _user, address _token)\n public\n view\n override\n returns (uint256)\n {\n uint256 balanceInNew = userTokenBalance(_user, _token);\n uint256 balanceInOld = oldTreasury.userTokenBalance(_user, _token);\n\n uint256 balance = balanceInNew + balanceInOld;\n\n return balance;\n }\n\n function _creditUser(\n address _user,\n address _token,\n uint256 _amount,\n uint256 _totalBalance\n ) internal {\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCredit = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n _totalBalance\n );\n\n if (sharesTotal == 0)\n require(\n sharesToCredit >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Require MIN_SHARES_IN_TREASURY\"\n );\n\n require(sharesToCredit > 0, \"TaskTreasury: Zero shares to credit\");\n\n shares[_user][_token] += sharesToCredit;\n totalShares[_token] = sharesTotal + sharesToCredit;\n\n _tokens[_user].add(_token);\n }\n\n function _deductUser(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesTotal = totalShares[_token];\n uint256 sharesToCharge = LibShares.tokenToShares(\n _token,\n _amount,\n sharesTotal,\n totalBalance\n );\n\n require(\n sharesTotal - sharesToCharge >= MIN_SHARES_IN_TREASURY,\n \"TaskTreasury: Below MIN_SHARES_IN_TREASURY\"\n );\n\n uint256 sharesOfUser = shares[_user][_token];\n\n shares[_user][_token] = sharesOfUser - sharesToCharge;\n totalShares[_token] = sharesTotal - sharesToCharge;\n\n if (sharesOfUser == sharesToCharge) _tokens[_user].remove(_token);\n }\n\n function _pay(\n address _user,\n address _token,\n uint256 _amount\n ) internal {\n address admin = _proxyAdmin();\n require(_user != admin, \"TaskTreasury: No proxy admin\");\n\n uint256 totalBalance = LibShares.contractBalance(_token);\n uint256 sharesToPay = LibShares.tokenToShares(\n _token,\n _amount,\n totalShares[_token],\n totalBalance\n );\n\n require(\n shares[_user][_token] >= sharesToPay,\n \"TaskTreasury: Not enough funds\"\n );\n shares[_user][_token] -= sharesToPay;\n shares[admin][_token] += sharesToPay;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/structs/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() initializer {}\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\n // contract may have been reentered.\n require(_initializing ? _isConstructor() : !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} modifier, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n function _isConstructor() private view returns (bool) {\n return !AddressUpgradeable.isContract(address(this));\n }\n}\n" + }, + "contracts/vendor/gelato/FGelato.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n// solhint-disable private-vars-leading-underscore\n// solhint-disable func-visibility\nfunction _transfer(\n address payable _to,\n address _paymentToken,\n uint256 _amount\n) {\n if (_paymentToken == ETH) {\n (bool success, ) = _to.call{value: _amount}(\"\");\n require(success, \"_transfer: ETH transfer failed\");\n } else {\n SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxied.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nabstract contract Proxied {\n /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them\n /// It also allows these functions to be called inside a contructor\n /// even if the contract is meant to be used without proxy\n modifier proxied() {\n address proxyAdminAddress = _proxyAdmin();\n // With hardhat-deploy proxies\n // the proxyAdminAddress is zero only for the implementation contract\n // if the implementation contract want to be used as a standalone/immutable contract\n // it simply has to execute the `proxied` function\n // This ensure the proxyAdminAddress is never zero post deployment\n // And allow you to keep the same code for both proxied contract and immutable contract\n if (proxyAdminAddress == address(0)) {\n // ensure can not be called twice when used outside of proxy : no admin\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n )\n }\n } else {\n require(msg.sender == proxyAdminAddress);\n }\n _;\n }\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n}\n" + }, + "contracts/interfaces/ITaskTreasury.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasury {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address token,\n uint256 amount,\n address user\n ) external;\n\n function addWhitelistedService(address service) external;\n\n function removeWhitelistedService(address service) external;\n\n /// @notice External view functions ///\n\n function gelato() external view returns (address);\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/interfaces/ITaskTreasuryUpgradable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ITaskTreasuryUpgradable {\n /// @notice Events ///\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n event LogDeductFees(\n address indexed user,\n address indexed executor,\n address indexed token,\n uint256 fees,\n address service\n );\n\n event UpdatedService(address indexed service, bool add);\n\n event UpdatedMaxFee(uint256 indexed maxFee);\n\n /// @notice External functions ///\n\n function depositFunds(\n address receiver,\n address token,\n uint256 amount\n ) external payable;\n\n function withdrawFunds(\n address payable receiver,\n address token,\n uint256 amount\n ) external;\n\n function useFunds(\n address user,\n address token,\n uint256 amount\n ) external;\n\n function updateMaxFee(uint256 _newMaxFee) external;\n\n function updateWhitelistedService(address service, bool isWhitelist)\n external;\n\n /// @notice External view functions ///\n\n function getCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getTotalCreditTokensByUser(address user)\n external\n view\n returns (address[] memory);\n\n function getWhitelistedServices() external view returns (address[] memory);\n\n function totalUserTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n\n function userTokenBalance(address user, address token)\n external\n view\n returns (uint256);\n}\n" + }, + "contracts/libraries/LibShares.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\nimport {ETH} from \"../vendor/gelato/FGelato.sol\";\nimport {IERC20Extended} from \"../interfaces/IERC20Extended.sol\";\n\nlibrary LibShares {\n function contractBalance(address _token) internal view returns (uint256) {\n if (_token == ETH) {\n return address(this).balance;\n } else {\n return IERC20Extended(_token).balanceOf(address(this));\n }\n }\n\n function tokenToShares(\n address _token,\n uint256 _tokenAmount,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal view returns (uint256) {\n uint256 sharesOfToken;\n\n uint256 tokenIn18Dp = to18Dp(_token, _tokenAmount);\n uint256 totalBalanceIn18Dp = to18Dp(_token, _totalBalance);\n\n // credit shares equivalent to token amount\n if (_totalShares == 0 || _totalBalance == 0) {\n sharesOfToken = tokenIn18Dp;\n } else {\n sharesOfToken = divCeil(\n tokenIn18Dp * _totalShares,\n totalBalanceIn18Dp\n );\n }\n\n return sharesOfToken;\n }\n\n function to18Dp(address _token, uint256 _amount)\n internal\n view\n returns (uint256)\n {\n if (_token == ETH) return _amount;\n uint256 decimals = IERC20Extended(_token).decimals();\n\n if (decimals < 18) {\n return _amount * 10**(18 - decimals);\n } else {\n return _amount / 10**(decimals - 18);\n }\n }\n\n function sharesToToken(\n uint256 _shares,\n uint256 _totalShares,\n uint256 _totalBalance\n ) internal pure returns (uint256) {\n uint256 tokenOfShares;\n\n if (_totalShares == 0 || _totalBalance == 0) {\n tokenOfShares = 0;\n } else {\n tokenOfShares = (_shares * _totalBalance) / _totalShares;\n }\n\n return tokenOfShares;\n }\n\n function divCeil(uint256 x, uint256 y) internal pure returns (uint256) {\n uint256 remainder = x % y;\n uint256 result;\n\n if (remainder == 0) {\n result = x / y;\n } else {\n result = ((x - remainder) + y) / y;\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n assembly {\n size := extcodesize(account)\n }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/interfaces/IERC20Extended.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Extended {\n function decimals() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender)\n external\n view\n returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(\n address indexed owner,\n address indexed spender,\n uint256 value\n );\n}\n" + }, + "contracts/taskTreasury/TaskTreasuryL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\n// solhint-disable max-states-count\n// solhint-disable max-line-length\ncontract TaskTreasuryL2 is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n uint256 public maxFee;\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato, uint256 _maxFee) {\n gelato = _gelato;\n maxFee = _maxFee;\n }\n\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n if (maxFee != 0)\n require(maxFee >= _amount, \"TaskTreasury: useFunds: Overchared\");\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n /// @notice Change maxFee charged by Gelato (only relevant on Layer2s)\n /// @param _newMaxFee New Max Fee to charge\n function setMaxFee(uint256 _newMaxFee) external onlyOwner {\n maxFee = _newMaxFee;\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/ReentrancyGuard.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a / b + (a % b == 0 ? 0 : 1);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "contracts/taskTreasury/TaskTreasury.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {\n ReentrancyGuard\n} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Math} from \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport {_transfer, ETH} from \"../vendor/gelato/FGelato.sol\";\n\ncontract TaskTreasury is Ownable, ReentrancyGuard {\n using EnumerableSet for EnumerableSet.AddressSet;\n using SafeERC20 for IERC20;\n\n mapping(address => mapping(address => uint256)) public userTokenBalance;\n mapping(address => EnumerableSet.AddressSet) internal _tokenCredits;\n EnumerableSet.AddressSet internal _whitelistedServices;\n address payable public immutable gelato;\n\n event FundsDeposited(\n address indexed sender,\n address indexed token,\n uint256 indexed amount\n );\n event FundsWithdrawn(\n address indexed receiver,\n address indexed initiator,\n address indexed token,\n uint256 amount\n );\n\n modifier onlyWhitelistedServices() {\n require(\n _whitelistedServices.contains(msg.sender),\n \"TaskTreasury: onlyWhitelistedServices\"\n );\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n\n // solhint-disable max-line-length\n /// @notice Function to deposit Funds which will be used to execute transactions on various services\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function depositFunds(\n address _receiver,\n address _token,\n uint256 _amount\n ) external payable {\n uint256 depositAmount;\n if (_token == ETH) {\n depositAmount = msg.value;\n } else {\n IERC20 token = IERC20(_token);\n uint256 preBalance = token.balanceOf(address(this));\n token.safeTransferFrom(msg.sender, address(this), _amount);\n uint256 postBalance = token.balanceOf(address(this));\n depositAmount = postBalance - preBalance;\n }\n\n userTokenBalance[_receiver][_token] =\n userTokenBalance[_receiver][_token] +\n depositAmount;\n\n if (!_tokenCredits[_receiver].contains(_token))\n _tokenCredits[_receiver].add(_token);\n\n emit FundsDeposited(_receiver, _token, depositAmount);\n }\n\n /// @notice Function to withdraw Funds back to the _receiver\n /// @param _receiver Address receiving the credits\n /// @param _token Token to be credited, use \"0xeeee....\" for ETH\n /// @param _amount Amount to be credited\n function withdrawFunds(\n address payable _receiver,\n address _token,\n uint256 _amount\n ) external nonReentrant {\n uint256 balance = userTokenBalance[msg.sender][_token];\n\n uint256 withdrawAmount = Math.min(balance, _amount);\n\n userTokenBalance[msg.sender][_token] = balance - withdrawAmount;\n\n _transfer(_receiver, _token, withdrawAmount);\n\n if (withdrawAmount == balance) _tokenCredits[msg.sender].remove(_token);\n\n emit FundsWithdrawn(_receiver, msg.sender, _token, withdrawAmount);\n }\n\n /// @notice Function called by whitelisted services to handle payments, e.g. Ops\"\n /// @param _token Token to be used for payment by users\n /// @param _amount Amount to be deducted\n /// @param _user Address of user whose balance will be deducted\n function useFunds(\n address _token,\n uint256 _amount,\n address _user\n ) external onlyWhitelistedServices {\n userTokenBalance[_user][_token] =\n userTokenBalance[_user][_token] -\n _amount;\n\n if (userTokenBalance[_user][_token] == 0)\n _tokenCredits[_user].remove(_token);\n\n _transfer(gelato, _token, _amount);\n }\n\n // Governance functions\n\n /// @notice Add new service that can call useFunds. Gelato Governance\n /// @param _service New service to add\n function addWhitelistedService(address _service) external onlyOwner {\n require(\n !_whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: whitelisted\"\n );\n _whitelistedServices.add(_service);\n }\n\n /// @notice Remove old service that can call useFunds. Gelato Governance\n /// @param _service Old service to remove\n function removeWhitelistedService(address _service) external onlyOwner {\n require(\n _whitelistedServices.contains(_service),\n \"TaskTreasury: addWhitelistedService: !whitelisted\"\n );\n _whitelistedServices.remove(_service);\n }\n\n // View Funcs\n\n /// @notice Helper func to get all deposited tokens by a user\n /// @param _user User to get the balances from\n function getCreditTokensByUser(address _user)\n external\n view\n returns (address[] memory)\n {\n uint256 length = _tokenCredits[_user].length();\n address[] memory creditTokens = new address[](length);\n\n for (uint256 i; i < length; i++) {\n creditTokens[i] = _tokenCredits[_user].at(i);\n }\n return creditTokens;\n }\n\n function getWhitelistedServices() external view returns (address[] memory) {\n uint256 length = _whitelistedServices.length();\n address[] memory whitelistedServices = new address[](length);\n\n for (uint256 i; i < length; i++) {\n whitelistedServices[i] = _whitelistedServices.at(i);\n }\n return whitelistedServices;\n }\n}\n" + }, + "contracts/Ops.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.12;\n\nimport {Gelatofied} from \"./vendor/gelato/Gelatofied.sol\";\nimport {GelatoBytes} from \"./vendor/gelato/GelatoBytes.sol\";\nimport {\n EnumerableSet\n} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {\n ITaskTreasuryUpgradable\n} from \"./interfaces/ITaskTreasuryUpgradable.sol\";\n\n// solhint-disable max-line-length\n// solhint-disable max-states-count\n// solhint-disable not-rely-on-time\n/// @notice Ops enables everyone to communicate to Gelato Bots to monitor and execute certain transactions\n/// @notice ResolverAddresses determine when Gelato should execute and provides bots with\n/// the payload they should use to execute\n/// @notice ExecAddress determine the actual contracts to execute a function on\ncontract Ops is Gelatofied {\n using SafeERC20 for IERC20;\n using GelatoBytes for bytes;\n using EnumerableSet for EnumerableSet.Bytes32Set;\n\n struct Time {\n uint128 nextExec;\n uint128 interval;\n }\n\n // solhint-disable const-name-snakecase\n string public constant version = \"4\";\n mapping(bytes32 => address) public taskCreator;\n mapping(bytes32 => address) public execAddresses;\n mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks;\n ITaskTreasuryUpgradable public immutable taskTreasury;\n uint256 public fee;\n address public feeToken;\n // Appended State\n mapping(bytes32 => Time) public timedTask;\n\n event ExecSuccess(\n uint256 indexed txFee,\n address indexed feeToken,\n address indexed execAddress,\n bytes execData,\n bytes32 taskId,\n bool callSuccess\n );\n event TaskCreated(\n address taskCreator,\n address execAddress,\n bytes4 selector,\n address resolverAddress,\n bytes32 taskId,\n bytes resolverData,\n bool useTaskTreasuryFunds,\n address feeToken,\n bytes32 resolverHash\n );\n event TaskCancelled(bytes32 taskId, address taskCreator);\n event TimerSet(\n bytes32 indexed taskId,\n uint128 indexed nextExec,\n uint128 indexed interval\n );\n\n constructor(address payable _gelato, ITaskTreasuryUpgradable _taskTreasury)\n Gelatofied(_gelato)\n {\n taskTreasury = _taskTreasury;\n }\n\n /// @notice Execution API called by Gelato\n /// @param _txFee Fee paid to Gelato for execution, deducted on the TaskTreasury\n /// @param _feeToken Token used to pay for the execution. ETH = 0xeeeeee...\n /// @param _taskCreator On which contract should Gelato check when to execute the tx\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _revertOnFailure To revert or not if call to execAddress fails\n /// @param _execAddress On which contract should Gelato execute the tx\n /// @param _execData Data used to execute the tx, queried from the Resolver by Gelato\n // solhint-disable function-max-lines\n // solhint-disable code-complexity\n function exec(\n uint256 _txFee,\n address _feeToken,\n address _taskCreator,\n bool _useTaskTreasuryFunds,\n bool _revertOnFailure,\n bytes32 _resolverHash,\n address _execAddress,\n bytes calldata _execData\n ) external onlyGelato {\n bytes32 task = getTaskId(\n _taskCreator,\n _execAddress,\n _execData.calldataSliceSelector(),\n _useTaskTreasuryFunds,\n _useTaskTreasuryFunds ? address(0) : _feeToken,\n _resolverHash\n );\n\n require(taskCreator[task] == _taskCreator, \"Ops: exec: No task found\");\n\n if (!_useTaskTreasuryFunds) {\n fee = _txFee;\n feeToken = _feeToken;\n }\n\n _updateTime(task);\n\n (bool success, bytes memory returnData) = _execAddress.call(_execData);\n\n // For off-chain simultaion\n if (!success && _revertOnFailure)\n returnData.revertWithError(\"Ops.exec:\");\n\n if (_useTaskTreasuryFunds) {\n taskTreasury.useFunds(_taskCreator, _feeToken, _txFee);\n } else {\n delete fee;\n delete feeToken;\n }\n\n emit ExecSuccess(\n _txFee,\n _feeToken,\n _execAddress,\n _execData,\n task,\n success\n );\n }\n\n /// @notice Helper func to query fee and feeToken\n function getFeeDetails() external view returns (uint256, address) {\n return (fee, feeToken);\n }\n\n /// @notice Helper func to query all open tasks by a task creator\n /// @param _taskCreator Address who created the task\n function getTaskIdsByUser(address _taskCreator)\n external\n view\n returns (bytes32[] memory)\n {\n uint256 length = _createdTasks[_taskCreator].length();\n bytes32[] memory taskIds = new bytes32[](length);\n\n for (uint256 i; i < length; i++) {\n taskIds[i] = _createdTasks[_taskCreator].at(i);\n }\n\n return taskIds;\n }\n\n /// @notice Helper func to query the _selector of a function you want to automate\n /// @param _func String of the function you want the selector from\n /// @dev Example: \"transferFrom(address,address,uint256)\" => 0x23b872dd\n function getSelector(string calldata _func) external pure returns (bytes4) {\n return bytes4(keccak256(bytes(_func)));\n }\n\n /// @notice Create a timed task that executes every so often based on the inputted interval\n /// @param _startTime Timestamp when the first task should become executable. 0 for right now\n /// @param _interval After how many seconds should each task be executed\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n /// @param _useTreasury True if Gelato should charge fees from TaskTreasury, false if not\n function createTimedTask(\n uint128 _startTime,\n uint128 _interval,\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken,\n bool _useTreasury\n ) public returns (bytes32 task) {\n require(_interval > 0, \"Ops: createTimedTask: interval cannot be 0\");\n\n if (_useTreasury) {\n task = createTask(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData\n );\n } else {\n task = createTaskNoPrepayment(\n _execAddress,\n _execSelector,\n _resolverAddress,\n _resolverData,\n _feeToken\n );\n }\n\n uint128 nextExec = uint256(_startTime) > block.timestamp\n ? _startTime\n : uint128(block.timestamp);\n\n timedTask[task] = Time({nextExec: nextExec, interval: _interval});\n emit TimerSet(task, nextExec, _interval);\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires funds to be added in Task Treasury, assumes treasury sends fee to Gelato via Ops\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n function createTask(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n true,\n address(0),\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n true,\n address(0),\n resolverHash\n );\n }\n\n /// @notice Create a task that tells Gelato to monitor and execute transactions on specific contracts\n /// @dev Requires no funds to be added in Task Treasury, assumes tasks sends fee to Gelato directly\n /// @param _execAddress On which contract should Gelato execute the transactions\n /// @param _execSelector Which function Gelato should eecute on the _execAddress\n /// @param _resolverAddress On which contract should Gelato check when to execute the tx\n /// @param _resolverData Which data should be used to check on the Resolver when to execute the tx\n /// @param _feeToken Which token to use as fee payment\n function createTaskNoPrepayment(\n address _execAddress,\n bytes4 _execSelector,\n address _resolverAddress,\n bytes calldata _resolverData,\n address _feeToken\n ) public returns (bytes32 task) {\n bytes32 resolverHash = getResolverHash(_resolverAddress, _resolverData);\n task = getTaskId(\n msg.sender,\n _execAddress,\n _execSelector,\n false,\n _feeToken,\n resolverHash\n );\n\n require(\n taskCreator[task] == address(0),\n \"Ops: createTask: Sender already started task\"\n );\n\n _createdTasks[msg.sender].add(task);\n taskCreator[task] = msg.sender;\n execAddresses[task] = _execAddress;\n\n emit TaskCreated(\n msg.sender,\n _execAddress,\n _execSelector,\n _resolverAddress,\n task,\n _resolverData,\n false,\n _feeToken,\n resolverHash\n );\n }\n\n /// @notice Cancel a task so that Gelato can no longer execute it\n /// @param _taskId The hash of the task, can be computed using getTaskId()\n function cancelTask(bytes32 _taskId) public {\n require(\n taskCreator[_taskId] == msg.sender,\n \"Ops: cancelTask: Sender did not start task yet\"\n );\n\n _createdTasks[msg.sender].remove(_taskId);\n delete taskCreator[_taskId];\n delete execAddresses[_taskId];\n\n Time memory time = timedTask[_taskId];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n if (isTimedTask) delete timedTask[_taskId];\n\n emit TaskCancelled(_taskId, msg.sender);\n }\n\n /// @notice Helper func to query the resolverHash\n /// @param _resolverAddress Address of resolver\n /// @param _resolverData Data passed to resolver\n function getResolverHash(\n address _resolverAddress,\n bytes memory _resolverData\n ) public pure returns (bytes32) {\n return keccak256(abi.encode(_resolverAddress, _resolverData));\n }\n\n /// @notice Returns TaskId of a task Creator\n /// @param _taskCreator Address of the task creator\n /// @param _execAddress Address of the contract to be executed by Gelato\n /// @param _selector Function on the _execAddress which should be executed\n /// @param _useTaskTreasuryFunds If msg.sender's balance on TaskTreasury should pay for the tx\n /// @param _feeToken FeeToken to use, address 0 if task treasury is used\n /// @param _resolverHash hash of resolver address and data\n function getTaskId(\n address _taskCreator,\n address _execAddress,\n bytes4 _selector,\n bool _useTaskTreasuryFunds,\n address _feeToken,\n bytes32 _resolverHash\n ) public pure returns (bytes32) {\n return\n keccak256(\n abi.encode(\n _taskCreator,\n _execAddress,\n _selector,\n _useTaskTreasuryFunds,\n _feeToken,\n _resolverHash\n )\n );\n }\n\n function _updateTime(bytes32 task) internal {\n Time storage time = timedTask[task];\n bool isTimedTask = time.nextExec != 0 ? true : false;\n\n if (isTimedTask) {\n require(\n time.nextExec <= uint128(block.timestamp),\n \"Ops: exec: Too early\"\n );\n // If next execution would also be executed right now, skip forward to\n // the next execution in the future\n uint128 nextExec = time.nextExec + time.interval;\n uint128 timestamp = uint128(block.timestamp);\n while (timestamp >= nextExec) {\n nextExec = nextExec + time.interval;\n }\n time.nextExec = nextExec;\n }\n }\n}\n" + }, + "contracts/vendor/gelato/Gelatofied.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport {\n SafeERC20,\n IERC20\n} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {_transfer, ETH} from \"./FGelato.sol\";\n\nabstract contract Gelatofied {\n address payable public immutable gelato;\n\n modifier gelatofy(uint256 _amount, address _paymentToken) {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n _transfer(gelato, _paymentToken, _amount);\n }\n\n modifier onlyGelato() {\n require(msg.sender == gelato, \"Gelatofied: Only gelato\");\n _;\n }\n\n constructor(address payable _gelato) {\n gelato = _gelato;\n }\n}\n" + }, + "contracts/vendor/gelato/GelatoBytes.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nlibrary GelatoBytes {\n function calldataSliceSelector(bytes calldata _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function memorySliceSelector(bytes memory _bytes)\n internal\n pure\n returns (bytes4 selector)\n {\n selector =\n _bytes[0] |\n (bytes4(_bytes[1]) >> 8) |\n (bytes4(_bytes[2]) >> 16) |\n (bytes4(_bytes[3]) >> 24);\n }\n\n function revertWithError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n revert(string(abi.encodePacked(_tracingInfo, string(_bytes))));\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"))\n );\n }\n } else {\n revert(\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"))\n );\n }\n }\n\n function returnError(bytes memory _bytes, string memory _tracingInfo)\n internal\n pure\n returns (string memory)\n {\n // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err\n if (_bytes.length % 32 == 4) {\n bytes4 selector;\n assembly {\n selector := mload(add(0x20, _bytes))\n }\n if (selector == 0x08c379a0) {\n // Function selector for Error(string)\n assembly {\n _bytes := add(_bytes, 68)\n }\n return string(abi.encodePacked(_tracingInfo, string(_bytes)));\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"NoErrorSelector\"));\n }\n } else {\n return\n string(abi.encodePacked(_tracingInfo, \"UnexpectedReturndata\"));\n }\n }\n}\n" + }, + "contracts/Forwarder.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.0;\n\ncontract Forwarder {\n function checker(bytes memory execData)\n external\n pure\n returns (bool, bytes memory)\n {\n return (true, execData);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./Proxy.sol\";\n\ninterface ERC165 {\n function supportsInterface(bytes4 id) external view returns (bool);\n}\n\n///@notice Proxy implementing EIP173 for ownership management\ncontract EIP173Proxy is Proxy {\n // ////////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////\n\n event ProxyAdminTransferred(\n address indexed previousAdmin,\n address indexed newAdmin\n );\n\n // /////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////////////\n\n constructor(\n address implementationAddress,\n address adminAddress,\n bytes memory data\n ) payable {\n _setImplementation(implementationAddress, data);\n _setProxyAdmin(adminAddress);\n }\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n function proxyAdmin() external view returns (address) {\n return _proxyAdmin();\n }\n\n function supportsInterface(bytes4 id) external view returns (bool) {\n if (id == 0x01ffc9a7 || id == 0x7f5828d0) {\n return true;\n }\n if (id == 0xFFFFFFFF) {\n return false;\n }\n\n ERC165 implementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n implementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure\n // because it is itself inside `supportsInterface` that might only get 30,000 gas.\n // In practise this is unlikely to be an issue.\n try implementation.supportsInterface(id) returns (bool support) {\n return support;\n } catch {\n return false;\n }\n }\n\n function transferProxyAdmin(address newAdmin) external onlyProxyAdmin {\n _setProxyAdmin(newAdmin);\n }\n\n function upgradeTo(address newImplementation) external onlyProxyAdmin {\n _setImplementation(newImplementation, \"\");\n }\n\n function upgradeToAndCall(address newImplementation, bytes calldata data)\n external\n payable\n onlyProxyAdmin\n {\n _setImplementation(newImplementation, data);\n }\n\n // /////////////////////// MODIFIERS ////////////////////////////////////////////////////////////////////////\n\n modifier onlyProxyAdmin() {\n require(msg.sender == _proxyAdmin(), \"NOT_AUTHORIZED\");\n _;\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _proxyAdmin() internal view returns (address adminAddress) {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n adminAddress := sload(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103\n )\n }\n }\n\n function _setProxyAdmin(address newAdmin) internal {\n address previousAdmin = _proxyAdmin();\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103,\n newAdmin\n )\n }\n emit ProxyAdminTransferred(previousAdmin, newAdmin);\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/Proxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// EIP-1967\nabstract contract Proxy {\n // /////////////////////// EVENTS ///////////////////////////////////////////////////////////////////////////\n\n event ProxyImplementationUpdated(\n address indexed previousImplementation,\n address indexed newImplementation\n );\n\n // ///////////////////// EXTERNAL ///////////////////////////////////////////////////////////////////////////\n\n // prettier-ignore\n receive() external payable virtual {\n revert(\"ETHER_REJECTED\"); // explicit reject by default\n }\n\n fallback() external payable {\n _fallback();\n }\n\n // ///////////////////////// INTERNAL //////////////////////////////////////////////////////////////////////\n\n function _fallback() internal {\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n let implementationAddress := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n calldatacopy(0x0, 0x0, calldatasize())\n let success := delegatecall(\n gas(),\n implementationAddress,\n 0x0,\n calldatasize(),\n 0,\n 0\n )\n let retSz := returndatasize()\n returndatacopy(0, 0, retSz)\n switch success\n case 0 {\n revert(0, retSz)\n }\n default {\n return(0, retSz)\n }\n }\n }\n\n function _setImplementation(address newImplementation, bytes memory data)\n internal\n {\n address previousImplementation;\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n previousImplementation := sload(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc\n )\n }\n\n // solhint-disable-next-line security/no-inline-assembly\n assembly {\n sstore(\n 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc,\n newImplementation\n )\n }\n\n emit ProxyImplementationUpdated(\n previousImplementation,\n newImplementation\n );\n\n if (data.length > 0) {\n (bool success, ) = newImplementation.delegatecall(data);\n if (!success) {\n assembly {\n // This assembly ensure the revert contains the exact string data\n let returnDataSize := returndatasize()\n returndatacopy(0, 0, returnDataSize)\n revert(0, returnDataSize)\n }\n }\n }\n }\n}\n" + }, + "contracts/vendor/proxy/EIP173/EIP173ProxyWithCustomReceive.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./EIP173Proxy.sol\";\n\n///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive\ncontract EIP173ProxyWithCustomReceive is EIP173Proxy {\n constructor(\n address implementationAddress,\n address ownerAddress,\n bytes memory data\n ) payable EIP173Proxy(implementationAddress, ownerAddress, data) {}\n\n receive() external payable override {\n _fallback();\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/dist/hardhat.config.js b/dist/hardhat.config.js deleted file mode 100644 index c4e1565a..00000000 --- a/dist/hardhat.config.js +++ /dev/null @@ -1,134 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -// PLUGINS -require("@nomiclabs/hardhat-ethers"); -require("@nomiclabs/hardhat-waffle"); -require("@nomiclabs/hardhat-etherscan"); -require("@typechain/hardhat"); -require("hardhat-deploy"); -require("hardhat-deploy-ethers"); -// Process Env Variables -const dotenv = __importStar(require("dotenv")); -dotenv.config({ path: __dirname + "/.env" }); -// Libraries -const assert_1 = __importDefault(require("assert")); -const ethers_1 = require("ethers"); -// @dev Put this in .env -const ALCHEMY_ID = process.env.ALCHEMY_ID; -assert_1.default.ok(ALCHEMY_ID, "no Alchemy ID in process.env"); -// @dev fill this out -const DEPLOYER_PK_MAINNET = process.env.DEPLOYER_PK_MAINNET; -const DEPLOYER_PK_ROPSTEN = process.env.DEPLOYER_PK_ROPSTEN; -const ETHERSCAN_API = process.env.ETHERSCAN_API; -// const ETHERSCAN_MATIC_API = process.env.ETHERSCAN_MATIC_API; -// const ETHERSCAN_FANTOM_API = process.env.ETHERSCAN_FANTOM_API; -// const ETHERSCAN_ARBITRUM_API = process.env.ETHERSCAN_ARBITRUM_API; -// const ETHERSCAN_BSC_API = process.env.ETHERSCAN_BSC_API; -// const ETHERSCAN_AVALANCHE_API = process.env.ETHERSCAN_AVALANCHE_API; -// ================================= CONFIG ========================================= -const config = { - defaultNetwork: "hardhat", - // hardhat-deploy - namedAccounts: { - deployer: { - default: 0, - }, - }, - networks: { - hardhat: { - // Standard config - // timeout: 150000, - forking: { - url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - blockNumber: 12901600, - }, - }, - arbitrum: { - url: `https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`, - chainId: 42161, - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - }, - avalanche: { - url: "https://api.avax.network/ext/bc/C/rpc", - chainId: 43114, - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - }, - bsc: { - url: "https://bsc-dataseed.binance.org/", - chainId: 56, - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - }, - fantom: { - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - chainId: 250, - url: `https://rpcapi.fantom.network/`, - gasPrice: parseInt(ethers_1.utils.parseUnits("80", "gwei").toString()), - }, - goerli: { - accounts: DEPLOYER_PK_ROPSTEN ? [DEPLOYER_PK_ROPSTEN] : [], - chainId: 5, - url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(ethers_1.utils.parseUnits("7", "gwei").toString()), - }, - mainnet: { - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - chainId: 1, - url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(ethers_1.utils.parseUnits("100", "gwei").toString()), - }, - matic: { - url: `https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`, - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - gasPrice: parseInt(ethers_1.utils.parseUnits("30", "gwei").toString()), - }, - rinkeby: { - accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - chainId: 4, - url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(ethers_1.utils.parseUnits("7", "gwei").toString()), - }, - ropsten: { - accounts: DEPLOYER_PK_ROPSTEN ? [DEPLOYER_PK_ROPSTEN] : [], - chainId: 3, - url: `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(ethers_1.utils.parseUnits("7", "gwei").toString()), - }, - }, - solidity: { - compilers: [ - { - version: "0.8.0", - }, - ], - }, - typechain: { - outDir: "typechain", - target: "ethers-v5", - }, - etherscan: { - apiKey: ETHERSCAN_API, - }, -}; -exports.default = config; diff --git a/dist/hardhat/config/addresses.js b/dist/hardhat/config/addresses.js deleted file mode 100644 index 63e00bda..00000000 --- a/dist/hardhat/config/addresses.js +++ /dev/null @@ -1,38 +0,0 @@ -"use strict"; -/* eslint-disable @typescript-eslint/naming-convention */ -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getGelatoAddress = void 0; -const getGelatoAddress = (network) => { - const GELATO_MAINNET = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; - const GELATO_ROPSTEN = "0xCc4CcD69D31F9FfDBD3BFfDe49c6aA886DaB98d9"; - const GELATO_RINKEBY = "0x0630d1b8C2df3F0a68Df578D02075027a6397173"; - const GELATO_GOERLI = "0x683913B3A32ada4F8100458A3E1675425BdAa7DF"; - const GELATO_MATIC = "0x7598e84B2E114AB62CAB288CE5f7d5f6bad35BbA"; - const GELATO_FANTOM = "0xebA27A2301975FF5BF7864b99F55A4f7A457ED10"; - const GELATO_AVALANCHE = "0x7C5c4Af1618220C090A6863175de47afb20fa9Df"; - const GELATO_ARBITRUM = "0x4775aF8FEf4809fE10bf05867d2b038a4b5B2146"; - const GELATO_BSC = "0x7C5c4Af1618220C090A6863175de47afb20fa9Df"; - switch (network) { - case "mainnet": - return GELATO_MAINNET; - case "ropsten": - return GELATO_ROPSTEN; - case "rinkeby": - return GELATO_RINKEBY; - case "goerli": - return GELATO_GOERLI; - case "matic": - return GELATO_MATIC; - case "fantom": - return GELATO_FANTOM; - case "avalanche": - return GELATO_AVALANCHE; - case "arbitrum": - return GELATO_ARBITRUM; - case "bsc": - return GELATO_BSC; - case "hardhat": - return GELATO_MAINNET; - } -}; -exports.getGelatoAddress = getGelatoAddress; diff --git a/dist/test/Ops-WithoutTreasury.test.js b/dist/test/Ops-WithoutTreasury.test.js deleted file mode 100644 index 774bfe1d..00000000 --- a/dist/test/Ops-WithoutTreasury.test.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const chai_1 = require("chai"); -const helpers_1 = require("./helpers"); -const hre = require("hardhat"); -const { ethers, deployments } = hre; -const gelatoAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; -const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; -const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; -describe("Ops without treasury test", function () { - let ops; - let counter; - let counterResolver; - let taskTreasury; - let dai; - let user; - let userAddress; - let executor; - let executorAddress; - let resolverData; - let taskHashETH; - let taskHashDAI; - let selector; - let resolverHashETH; - let resolverHashDAI; - beforeEach(function () { - return __awaiter(this, void 0, void 0, function* () { - yield deployments.fixture(); - [user] = yield ethers.getSigners(); - userAddress = yield user.getAddress(); - ops = (yield ethers.getContract("Ops")); - taskTreasury = (yield ethers.getContract("TaskTreasury")); - counter = (yield ethers.getContract("CounterWithoutTreasury")); - counterResolver = (yield ethers.getContract("CounterResolverWithoutTreasury")); - dai = (yield ethers.getContractAt("IERC20", DAI)); - executorAddress = gelatoAddress; - yield taskTreasury.addWhitelistedService(ops.address); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [executorAddress], - }); - executor = yield ethers.provider.getSigner(executorAddress); - resolverData = yield counterResolver.interface.encodeFunctionData("checker"); - selector = yield ops.getSelector("increaseCount(uint256)"); - resolverHashETH = yield ops.getResolverHash(counterResolver.address, resolverData); - resolverHashDAI = yield ops.getResolverHash(counterResolver.address, resolverData); - taskHashETH = yield ops.getTaskId(userAddress, counter.address, selector, false, ETH, resolverHashETH); - taskHashDAI = yield ops.getTaskId(userAddress, counter.address, selector, false, DAI, resolverHashDAI); - yield chai_1.expect(ops - .connect(user) - .createTaskNoPrepayment(counter.address, selector, counterResolver.address, resolverData, ETH)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, counter.address, selector, counterResolver.address, taskHashETH, resolverData, false, ETH, resolverHashETH); - yield chai_1.expect(ops - .connect(user) - .createTaskNoPrepayment(counter.address, selector, counterResolver.address, resolverData, DAI)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, counter.address, selector, counterResolver.address, taskHashDAI, resolverData, false, DAI, resolverHashDAI); - }); - }); - it("canExec should be true, counter does not have enough ETH", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("0.5"); - yield user.sendTransaction({ - to: counter.address, - value: depositAmount, - }); - chai_1.expect(yield ethers.provider.getBalance(counter.address)).to.be.eq(depositAmount); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - // simulation should have failed - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), ETH, userAddress, false, false, resolverHashETH, counter.address, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("1"), ETH, counter.address, execData, taskHashETH, false); - })); - it("canExec should be true, counter does not have enough DAI", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("0.5"); - yield helpers_1.getTokenFromFaucet(DAI, counter.address, depositAmount); - chai_1.expect(yield dai.balanceOf(counter.address)).to.be.eq(depositAmount); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - // simulation should have failed - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, false, false, resolverHashDAI, counter.address, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("1"), DAI, counter.address, execData, taskHashDAI, false); - })); - it("canExec should be true, counter have enough ETH", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("5"); - yield user.sendTransaction({ - to: counter.address, - value: depositAmount, - }); - chai_1.expect(yield ethers.provider.getBalance(counter.address)).to.be.eq(depositAmount); - const gelatoBalanceBefore = yield ethers.provider.getBalance(gelatoAddress); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - yield ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), ETH, userAddress, false, false, resolverHashETH, counter.address, execData); - const gelatoBalanceAfter = yield ethers.provider.getBalance(gelatoAddress); - chai_1.expect(gelatoBalanceAfter).to.be.gt(gelatoBalanceBefore); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - })); - it("canExec should be true, counter does not have enough DAI", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("1"); - yield helpers_1.getTokenFromFaucet(DAI, counter.address, depositAmount); - chai_1.expect(yield dai.balanceOf(counter.address)).to.be.eq(depositAmount); - const gelatoDaiBefore = yield dai.balanceOf(gelatoAddress); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - yield ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, false, false, resolverHashDAI, counter.address, execData); - const gelatoDaiAfter = yield dai.balanceOf(gelatoAddress); - chai_1.expect(gelatoDaiAfter).to.be.gt(gelatoDaiBefore); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - })); -}); diff --git a/dist/test/Ops-createTimedTask.test.js b/dist/test/Ops-createTimedTask.test.js deleted file mode 100644 index f41a79bb..00000000 --- a/dist/test/Ops-createTimedTask.test.js +++ /dev/null @@ -1,143 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const chai_1 = require("chai"); -const hre = require("hardhat"); -const { ethers, deployments } = hre; -const gelatoAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; -const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; -const THREE_MINUTES = 3 * 60; -const FEETOKEN = ethers.constants.AddressZero; -describe("Ops createTimedTask test", function () { - this.timeout(0); - let ops; - let taskTreasury; - let forwarder; - let counter; - let user; - let userAddress; - let executor; - let executorAddress; - let interval; - let execAddress; - let execSelector; - let execData; - let resolverAddress; - let resolverData; - let taskId; - let resolverHash; - before(function () { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - yield deployments.fixture(); - [user] = yield ethers.getSigners(); - userAddress = yield user.getAddress(); - ops = (yield ethers.getContract("Ops")); - taskTreasury = (yield ethers.getContract("TaskTreasury")); - counter = (yield ethers.getContract("CounterTimedTask")); - forwarder = (yield ethers.getContract("Forwarder")); - executorAddress = gelatoAddress; - yield taskTreasury.addWhitelistedService(ops.address); - const depositAmount = ethers.utils.parseEther("1"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [executorAddress], - }); - executor = yield ethers.provider.getSigner(executorAddress); - execData = yield counter.interface.encodeFunctionData("increaseCount", [ - 100, - ]); - interval = THREE_MINUTES; - execAddress = counter.address; - execSelector = yield ops.getSelector("increaseCount(uint256)"); - resolverAddress = forwarder.address; - resolverData = yield forwarder.interface.encodeFunctionData("checker", [ - execData, - ]); - resolverHash = ethers.utils.keccak256(new ethers.utils.AbiCoder().encode(["address", "bytes"], [resolverAddress, resolverData])); - taskId = yield ops.getTaskId(userAddress, execAddress, execSelector, true, FEETOKEN, resolverHash); - const currentTimestamp = (_b = (yield ((_a = user.provider) === null || _a === void 0 ? void 0 : _a.getBlock("latest")))) === null || _b === void 0 ? void 0 : _b.timestamp; - yield chai_1.expect(ops - .connect(user) - .createTimedTask(currentTimestamp + interval, interval, execAddress, execSelector, resolverAddress, resolverData, FEETOKEN, true)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, execAddress, execSelector, resolverAddress, taskId, resolverData, true, FEETOKEN, resolverHash); - }); - }); - it("Exec should fail when time not elapsed", () => __awaiter(this, void 0, void 0, function* () { - const [canExec, payload] = yield forwarder.checker(execData); - chai_1.expect(payload).to.be.eql(execData); - chai_1.expect(canExec).to.be.eql(true); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, false, resolverHash, execAddress, execData)).to.be.revertedWith("Ops: exec: Too early"); - })); - it("Exec should succeed when time elapse", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - const nextExecBefore = (yield ops.timedTask(taskId)).nextExec; - yield counter.setExecutable(true); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, false, resolverHash, execAddress, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("0.1"), ETH, execAddress, execData, taskId, true); - const nextExecAfter = (yield ops.timedTask(taskId)).nextExec; - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.9")); - chai_1.expect(Number(yield counter.count())).to.be.eql(100); - chai_1.expect(nextExecAfter).to.be.gt(nextExecBefore); - })); - it("Exec should succeed even if txn fails", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - const nextExecBefore = (yield ops.timedTask(taskId)).nextExec; - yield counter.setExecutable(false); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, false, resolverHash, execAddress, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("0.1"), ETH, execAddress, execData, taskId, false); - const nextExecAfter = (yield ops.timedTask(taskId)).nextExec; - chai_1.expect(Number(yield counter.count())).to.be.eql(100); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.8")); - chai_1.expect(nextExecAfter).to.be.gt(nextExecBefore); - })); - it("should skip one interval", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [2 * THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - const nextExecBefore = (yield ops.timedTask(taskId)).nextExec; - yield counter.setExecutable(true); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, false, resolverHash, execAddress, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("0.1"), ETH, execAddress, execData, taskId, true); - const nextExecAfter = (yield ops.timedTask(taskId)).nextExec; - chai_1.expect(Number(yield counter.count())).to.be.eql(200); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.7")); - chai_1.expect(Number(nextExecAfter.sub(nextExecBefore))).to.be.eql(2 * THREE_MINUTES); - })); - it("Should account for drift", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [50 * THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - yield ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, false, resolverHash, execAddress, execData); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, false, resolverHash, execAddress, execData)).to.be.revertedWith("Ops: exec: Too early"); - chai_1.expect(Number(yield counter.count())).to.be.eql(300); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.6")); - })); -}); diff --git a/dist/test/Ops.test.js b/dist/test/Ops.test.js deleted file mode 100644 index 505bb42c..00000000 --- a/dist/test/Ops.test.js +++ /dev/null @@ -1,256 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const chai_1 = require("chai"); -const helpers_1 = require("./helpers"); -const hre = require("hardhat"); -const { ethers, deployments } = hre; -const diamondAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; -const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; -const DAI = "0x6b175474e89094c44da98b954eedeac495271d0f"; -describe("Ops test", function () { - let ops; - let counter; - let counterResolver; - let taskTreasury; - let dai; - let user; - let userAddress; - let user2; - let user2Address; - let diamondSigner; - let resolverData; - let taskHash; - let selector; - let resolverHash; - beforeEach(function () { - return __awaiter(this, void 0, void 0, function* () { - yield deployments.fixture(); - [user, user2] = yield hre.ethers.getSigners(); - userAddress = yield user.getAddress(); - user2Address = yield user2.getAddress(); - ops = (yield ethers.getContract("Ops")); - taskTreasury = (yield ethers.getContract("TaskTreasury")); - counter = (yield ethers.getContract("Counter")); - counterResolver = (yield ethers.getContract("CounterResolver")); - dai = (yield ethers.getContractAt("IERC20", DAI)); - yield taskTreasury.addWhitelistedService(ops.address); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [diamondAddress], - }); - diamondSigner = yield ethers.provider.getSigner(diamondAddress); - resolverData = counterResolver.interface.encodeFunctionData("checker"); - selector = yield ops.getSelector("increaseCount(uint256)"); - resolverHash = ethers.utils.keccak256(new ethers.utils.AbiCoder().encode(["address", "bytes"], [counterResolver.address, resolverData])); - taskHash = yield ops.getTaskId(userAddress, counter.address, selector, true, ethers.constants.AddressZero, resolverHash); - yield chai_1.expect(ops - .connect(user) - .createTask(counter.address, selector, counterResolver.address, resolverData)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, counter.address, selector, counterResolver.address, taskHash, resolverData, true, ethers.constants.AddressZero, resolverHash); - }); - }); - it("sender already started task", () => __awaiter(this, void 0, void 0, function* () { - yield chai_1.expect(ops - .connect(user) - .createTask(counter.address, selector, counterResolver.address, resolverData)).to.be.revertedWith("Ops: createTask: Sender already started task"); - })); - it("sender did not start task", () => __awaiter(this, void 0, void 0, function* () { - yield ops.connect(user).cancelTask(taskHash); - yield chai_1.expect(ops.connect(user).cancelTask(taskHash)).to.be.revertedWith("Ops: cancelTask: Sender did not start task yet"); - })); - it("deposit and withdraw ETH", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("1"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq(ethers.utils.parseEther("1")); - yield chai_1.expect(taskTreasury - .connect(user) - .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1"))) - .to.emit(taskTreasury, "FundsWithdrawn") - .withArgs(userAddress, userAddress, ETH, depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq(ethers.BigNumber.from("0")); - })); - it("deposit and withdraw DAI", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("1"); - const DAI_CHECKSUM = ethers.utils.getAddress(DAI); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.approve(taskTreasury.address, depositAmount); - yield chai_1.expect(taskTreasury.connect(user).depositFunds(userAddress, DAI, depositAmount)) - .to.emit(taskTreasury, "FundsDeposited") - .withArgs(userAddress, DAI_CHECKSUM, depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eq(ethers.utils.parseEther("1")); - yield chai_1.expect(taskTreasury.connect(user).withdrawFunds(userAddress, DAI, depositAmount)) - .to.emit(taskTreasury, "FundsWithdrawn") - .withArgs(userAddress, userAddress, DAI_CHECKSUM, depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eq(ethers.BigNumber.from("0")); - })); - it("user withdraw more ETH than balance", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("10"); - yield taskTreasury - .connect(user2) - .depositFunds(user2Address, ETH, depositAmount, { value: depositAmount }); - const balanceBefore = yield ethers.provider.getBalance(ops.address); - yield taskTreasury - .connect(user) - .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1")); - const balanceAfter = yield ethers.provider.getBalance(ops.address); - chai_1.expect(balanceAfter).to.be.eql(balanceBefore); - chai_1.expect(yield taskTreasury.userTokenBalance(user2Address, ETH)).to.be.eql(depositAmount); - chai_1.expect(Number(yield taskTreasury.userTokenBalance(userAddress, ETH))).to.be.eql(0); - })); - it("user withdraw more DAI than balance", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("10"); - yield helpers_1.getTokenFromFaucet(DAI, user2Address, depositAmount); - yield dai.connect(user2).approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user2) - .depositFunds(user2Address, DAI, depositAmount); - const balanceBefore = yield dai.balanceOf(taskTreasury.address); - yield taskTreasury - .connect(user) - .withdrawFunds(userAddress, DAI, ethers.utils.parseEther("1")); - const balanceAfter = yield dai.balanceOf(taskTreasury.address); - chai_1.expect(balanceAfter).to.be.eql(balanceBefore); - chai_1.expect(yield taskTreasury.userTokenBalance(user2Address, DAI)).to.be.eql(depositAmount); - chai_1.expect(Number(yield taskTreasury.userTokenBalance(userAddress, DAI))).to.be.eql(0); - })); - it("no task found when exec", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - yield ops.connect(user).cancelTask(taskHash); - const [, execData] = yield counterResolver.checker(); - yield chai_1.expect(ops - .connect(diamondSigner) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, true, false, resolverHash, counter.address, execData)).to.be.revertedWith("Ops: exec: No task found"); - })); - it("canExec should be true, caller does not have enough ETH", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("0.5"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - yield chai_1.expect(ops - .connect(diamondSigner) - .exec(ethers.utils.parseEther("1"), ETH, userAddress, true, false, resolverHash, counter.address, execData)).to.be.reverted; - })); - it("canExec should be true, caller does not have enough DAI", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - const depositAmount = ethers.utils.parseEther("0.5"); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.connect(user).approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, DAI, depositAmount); - yield chai_1.expect(ops - .connect(diamondSigner) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, true, false, resolverHash, counter.address, execData)).to.be.reverted; - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eql(depositAmount); - })); - it("should exec and pay with ETH", () => __awaiter(this, void 0, void 0, function* () { - const txFee = ethers.utils.parseEther("1"); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("0")); - const depositAmount = ethers.utils.parseEther("2"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - chai_1.expect(yield taskTreasury.connect(user).userTokenBalance(userAddress, ETH)).to.be.eq(depositAmount); - yield ops - .connect(diamondSigner) - .exec(txFee, ETH, userAddress, true, false, resolverHash, counter.address, execData); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - chai_1.expect(yield taskTreasury.connect(user).userTokenBalance(userAddress, ETH)).to.be.eq(depositAmount.sub(txFee)); - // time not elapsed - yield chai_1.expect(simulateExec(txFee, ETH, userAddress, true, resolverHash, counter.address, execData)).to.be.revertedWith("Ops.exec:Counter: increaseCount: Time not elapsed"); - })); - it("should exec and pay with DAI", () => __awaiter(this, void 0, void 0, function* () { - const txFee = ethers.utils.parseEther("1"); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("2"); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.connect(user).approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, DAI, depositAmount); - chai_1.expect(yield taskTreasury.connect(user).userTokenBalance(userAddress, DAI)).to.be.eq(depositAmount); - yield ops - .connect(diamondSigner) - .exec(txFee, DAI, userAddress, true, false, resolverHash, counter.address, execData); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - // time not elapsed - yield chai_1.expect(simulateExec(txFee, DAI, userAddress, true, resolverHash, counter.address, execData)).to.be.revertedWith("Ops.exec:Counter: increaseCount: Time not elapsed"); - })); - it("should exec and charge user even when it reverts", () => __awaiter(this, void 0, void 0, function* () { - const txFee = ethers.utils.parseEther("1"); - const [, execData] = yield counterResolver.checker(); - const depositAmount = ethers.utils.parseEther("2"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - // execute twice in a row - yield ops - .connect(diamondSigner) - .exec(txFee, ETH, userAddress, true, false, resolverHash, counter.address, execData); - const count = yield counter.count(); - chai_1.expect(count).to.be.eq(ethers.BigNumber.from("100")); - yield ops - .connect(diamondSigner) - .exec(txFee, ETH, userAddress, true, false, resolverHash, counter.address, execData); - chai_1.expect(yield counter.count()).to.be.eq(count); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq(ethers.BigNumber.from("0")); - })); - it("getTaskIdsByUser test", () => __awaiter(this, void 0, void 0, function* () { - // fake task - yield ops - .connect(user) - .createTask(userAddress, selector, counterResolver.address, resolverData); - const ids = yield ops.getTaskIdsByUser(userAddress); - chai_1.expect(ids.length).to.be.eql(2); - })); - it("getCreditTokensByUser test", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("1"); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, DAI, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eql(depositAmount); - })); - const simulateExec = (_txFee, _feeToken, _taskCreator, _useTaskTreasury, _resolverHash, _execAddress, _execData) => __awaiter(this, void 0, void 0, function* () { - yield ops - .connect(diamondSigner) - .exec(_txFee, _feeToken, _taskCreator, _useTaskTreasury, true, _resolverHash, _execAddress, _execData); - }); -}); diff --git a/dist/test/PokeMe-WithoutTreasury.test.js b/dist/test/PokeMe-WithoutTreasury.test.js deleted file mode 100644 index d2a9fed0..00000000 --- a/dist/test/PokeMe-WithoutTreasury.test.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const chai_1 = require("chai"); -const helpers_1 = require("./helpers"); -const hre = require("hardhat"); -const { ethers, deployments } = hre; -const gelatoAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; -const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; -const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; -describe("Ops without treasury test", function () { - let ops; - let counter; - let counterResolver; - let taskTreasury; - let dai; - let user; - let userAddress; - let executor; - let executorAddress; - let resolverData; - let taskHashETH; - let taskHashDAI; - let selector; - let resolverHashETH; - let resolverHashDAI; - beforeEach(function () { - return __awaiter(this, void 0, void 0, function* () { - yield deployments.fixture(); - [user] = yield ethers.getSigners(); - userAddress = yield user.getAddress(); - ops = (yield ethers.getContract("Ops")); - taskTreasury = (yield ethers.getContract("TaskTreasury")); - counter = (yield ethers.getContract("CounterWithoutTreasury")); - counterResolver = (yield ethers.getContract("CounterResolverWithoutTreasury")); - dai = (yield ethers.getContractAt("IERC20", DAI)); - executorAddress = gelatoAddress; - yield taskTreasury.addWhitelistedService(ops.address); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [executorAddress], - }); - executor = yield ethers.provider.getSigner(executorAddress); - resolverData = yield counterResolver.interface.encodeFunctionData("checker"); - selector = yield ops.getSelector("increaseCount(uint256)"); - resolverHashETH = yield ops.getResolverHash(counterResolver.address, resolverData); - resolverHashDAI = yield ops.getResolverHash(counterResolver.address, resolverData); - taskHashETH = yield ops.getTaskId(userAddress, counter.address, selector, false, ETH, resolverHashETH); - taskHashDAI = yield ops.getTaskId(userAddress, counter.address, selector, false, DAI, resolverHashDAI); - yield chai_1.expect(ops - .connect(user) - .createTaskNoPrepayment(counter.address, selector, counterResolver.address, resolverData, ETH)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, counter.address, selector, counterResolver.address, taskHashETH, resolverData, false, ETH, resolverHashETH); - yield chai_1.expect(ops - .connect(user) - .createTaskNoPrepayment(counter.address, selector, counterResolver.address, resolverData, DAI)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, counter.address, selector, counterResolver.address, taskHashDAI, resolverData, false, DAI, resolverHashDAI); - }); - }); - it("canExec should be true, counter does not have enough ETH", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("0.5"); - yield user.sendTransaction({ - to: counter.address, - value: depositAmount, - }); - chai_1.expect(yield ethers.provider.getBalance(counter.address)).to.be.eq(depositAmount); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - // simulation should have failed - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), ETH, userAddress, false, resolverHashETH, counter.address, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("1"), ETH, counter.address, execData, taskHashETH, false); - })); - it("canExec should be true, counter does not have enough DAI", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("0.5"); - yield helpers_1.getTokenFromFaucet(DAI, counter.address, depositAmount); - chai_1.expect(yield dai.balanceOf(counter.address)).to.be.eq(depositAmount); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - // simulation should have failed - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, false, resolverHashDAI, counter.address, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("1"), DAI, counter.address, execData, taskHashDAI, false); - })); - it("canExec should be true, counter have enough ETH", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("5"); - yield user.sendTransaction({ - to: counter.address, - value: depositAmount, - }); - chai_1.expect(yield ethers.provider.getBalance(counter.address)).to.be.eq(depositAmount); - const gelatoBalanceBefore = yield ethers.provider.getBalance(gelatoAddress); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - yield ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), ETH, userAddress, false, resolverHashETH, counter.address, execData); - const gelatoBalanceAfter = yield ethers.provider.getBalance(gelatoAddress); - chai_1.expect(gelatoBalanceAfter).to.be.gt(gelatoBalanceBefore); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - })); - it("canExec should be true, counter does not have enough DAI", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("1"); - yield helpers_1.getTokenFromFaucet(DAI, counter.address, depositAmount); - chai_1.expect(yield dai.balanceOf(counter.address)).to.be.eq(depositAmount); - const gelatoDaiBefore = yield dai.balanceOf(gelatoAddress); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - yield ops - .connect(executor) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, false, resolverHashDAI, counter.address, execData); - const gelatoDaiAfter = yield dai.balanceOf(gelatoAddress); - chai_1.expect(gelatoDaiAfter).to.be.gt(gelatoDaiBefore); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - })); -}); diff --git a/dist/test/PokeMe-createTimedTask.test.js b/dist/test/PokeMe-createTimedTask.test.js deleted file mode 100644 index c7cdd402..00000000 --- a/dist/test/PokeMe-createTimedTask.test.js +++ /dev/null @@ -1,143 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const chai_1 = require("chai"); -const hre = require("hardhat"); -const { ethers, deployments } = hre; -const gelatoAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; -const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; -const THREE_MINUTES = 3 * 60; -const FEETOKEN = ethers.constants.AddressZero; -describe("Ops createTimedTask test", function () { - this.timeout(0); - let ops; - let taskTreasury; - let forwarder; - let counter; - let user; - let userAddress; - let executor; - let executorAddress; - let interval; - let execAddress; - let execSelector; - let execData; - let resolverAddress; - let resolverData; - let taskId; - let resolverHash; - before(function () { - var _a, _b; - return __awaiter(this, void 0, void 0, function* () { - yield deployments.fixture(); - [user] = yield ethers.getSigners(); - userAddress = yield user.getAddress(); - ops = (yield ethers.getContract("Ops")); - taskTreasury = (yield ethers.getContract("TaskTreasury")); - counter = (yield ethers.getContract("CounterTimedTask")); - forwarder = (yield ethers.getContract("Forwarder")); - executorAddress = gelatoAddress; - yield taskTreasury.addWhitelistedService(ops.address); - const depositAmount = ethers.utils.parseEther("1"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [executorAddress], - }); - executor = yield ethers.provider.getSigner(executorAddress); - execData = yield counter.interface.encodeFunctionData("increaseCount", [ - 100, - ]); - interval = THREE_MINUTES; - execAddress = counter.address; - execSelector = yield ops.getSelector("increaseCount(uint256)"); - resolverAddress = forwarder.address; - resolverData = yield forwarder.interface.encodeFunctionData("checker", [ - execData, - ]); - resolverHash = ethers.utils.keccak256(new ethers.utils.AbiCoder().encode(["address", "bytes"], [resolverAddress, resolverData])); - taskId = yield ops.getTaskId(userAddress, execAddress, execSelector, true, FEETOKEN, resolverHash); - const currentTimestamp = (_b = (yield ((_a = user.provider) === null || _a === void 0 ? void 0 : _a.getBlock("latest")))) === null || _b === void 0 ? void 0 : _b.timestamp; - yield chai_1.expect(ops - .connect(user) - .createTimedTask(currentTimestamp + interval, interval, execAddress, execSelector, resolverAddress, resolverData, FEETOKEN, true)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, execAddress, execSelector, resolverAddress, taskId, resolverData, true, FEETOKEN, resolverHash); - }); - }); - it("Exec should fail when time not elapsed", () => __awaiter(this, void 0, void 0, function* () { - const [canExec, payload] = yield forwarder.checker(execData); - chai_1.expect(payload).to.be.eql(execData); - chai_1.expect(canExec).to.be.eql(true); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, resolverHash, execAddress, execData)).to.be.revertedWith("Ops: exec: Too early"); - })); - it("Exec should succeed when time elapse", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - const nextExecBefore = (yield ops.timedTask(taskId)).nextExec; - yield counter.setExecutable(true); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, resolverHash, execAddress, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("0.1"), ETH, execAddress, execData, taskId, true); - const nextExecAfter = (yield ops.timedTask(taskId)).nextExec; - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.9")); - chai_1.expect(Number(yield counter.count())).to.be.eql(100); - chai_1.expect(nextExecAfter).to.be.gt(nextExecBefore); - })); - it("Exec should succeed even if txn fails", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - const nextExecBefore = (yield ops.timedTask(taskId)).nextExec; - yield counter.setExecutable(false); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, resolverHash, execAddress, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("0.1"), ETH, execAddress, execData, taskId, false); - const nextExecAfter = (yield ops.timedTask(taskId)).nextExec; - chai_1.expect(Number(yield counter.count())).to.be.eql(100); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.8")); - chai_1.expect(nextExecAfter).to.be.gt(nextExecBefore); - })); - it("should skip one interval", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [2 * THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - const nextExecBefore = (yield ops.timedTask(taskId)).nextExec; - yield counter.setExecutable(true); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, resolverHash, execAddress, execData)) - .to.emit(ops, "ExecSuccess") - .withArgs(ethers.utils.parseEther("0.1"), ETH, execAddress, execData, taskId, true); - const nextExecAfter = (yield ops.timedTask(taskId)).nextExec; - chai_1.expect(Number(yield counter.count())).to.be.eql(200); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.7")); - chai_1.expect(Number(nextExecAfter.sub(nextExecBefore))).to.be.eql(2 * THREE_MINUTES); - })); - it("Should account for drift", () => __awaiter(this, void 0, void 0, function* () { - yield hre.network.provider.send("evm_increaseTime", [50 * THREE_MINUTES]); - yield hre.network.provider.send("evm_mine", []); - yield ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, resolverHash, execAddress, execData); - yield chai_1.expect(ops - .connect(executor) - .exec(ethers.utils.parseEther("0.1"), ETH, userAddress, true, resolverHash, execAddress, execData)).to.be.revertedWith("Ops: exec: Too early"); - chai_1.expect(Number(yield counter.count())).to.be.eql(300); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(ethers.utils.parseEther("0.6")); - })); -}); diff --git a/dist/test/PokeMe.test.js b/dist/test/PokeMe.test.js deleted file mode 100644 index ca3bea52..00000000 --- a/dist/test/PokeMe.test.js +++ /dev/null @@ -1,288 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const chai_1 = require("chai"); -const helpers_1 = require("./helpers"); -const hre = require("hardhat"); -const { ethers, deployments } = hre; -const execFacetAbi = [ - "function exec(address _service,bytes calldata _data,address _creditToken) external", - "function addExecutors(address[] calldata _executors) external", -]; -const ownerAddress = "0x163407FDA1a93941358c1bfda39a868599553b6D"; -const diamondAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; -const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; -const DAI = "0x6b175474e89094c44da98b954eedeac495271d0f"; -describe("Ops test", function () { - let ops; - let counter; - let counterResolver; - let taskTreasury; - let dai; - let diamond; - let user; - let userAddress; - let user2; - let user2Address; - let owner; - let diamondSigner; - let resolverData; - let taskHash; - let selector; - let resolverHash; - beforeEach(function () { - return __awaiter(this, void 0, void 0, function* () { - yield deployments.fixture(); - [user, user2] = yield hre.ethers.getSigners(); - userAddress = yield user.getAddress(); - user2Address = yield user2.getAddress(); - ops = (yield ethers.getContract("Ops")); - taskTreasury = (yield ethers.getContract("TaskTreasury")); - counter = (yield ethers.getContract("Counter")); - counterResolver = (yield ethers.getContract("CounterResolver")); - dai = (yield ethers.getContractAt("IERC20", DAI)); - diamond = yield ethers.getContractAt(execFacetAbi, diamondAddress); - yield taskTreasury.addWhitelistedService(ops.address); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [ownerAddress], - }); - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [diamondAddress], - }); - owner = yield ethers.provider.getSigner(ownerAddress); - diamondSigner = yield ethers.provider.getSigner(diamondAddress); - resolverData = counterResolver.interface.encodeFunctionData("checker"); - selector = yield ops.getSelector("increaseCount(uint256)"); - resolverHash = ethers.utils.keccak256(new ethers.utils.AbiCoder().encode(["address", "bytes"], [counterResolver.address, resolverData])); - taskHash = yield ops.getTaskId(userAddress, counter.address, selector, true, ethers.constants.AddressZero, resolverHash); - yield chai_1.expect(ops - .connect(user) - .createTask(counter.address, selector, counterResolver.address, resolverData)) - .to.emit(ops, "TaskCreated") - .withArgs(userAddress, counter.address, selector, counterResolver.address, taskHash, resolverData, true, ethers.constants.AddressZero, resolverHash); - }); - }); - it("sender already started task", () => __awaiter(this, void 0, void 0, function* () { - yield chai_1.expect(ops - .connect(user) - .createTask(counter.address, selector, counterResolver.address, resolverData)).to.be.revertedWith("Ops: createTask: Sender already started task"); - })); - it("sender did not start task", () => __awaiter(this, void 0, void 0, function* () { - yield ops.connect(user).cancelTask(taskHash); - yield chai_1.expect(ops.connect(user).cancelTask(taskHash)).to.be.revertedWith("Ops: cancelTask: Sender did not start task yet"); - })); - it("deposit and withdraw ETH", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("1"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq(ethers.utils.parseEther("1")); - yield chai_1.expect(taskTreasury - .connect(user) - .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1"))) - .to.emit(taskTreasury, "FundsWithdrawn") - .withArgs(userAddress, userAddress, ETH, depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq(ethers.BigNumber.from("0")); - })); - it("deposit and withdraw DAI", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("1"); - const DAI_CHECKSUM = ethers.utils.getAddress(DAI); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.approve(taskTreasury.address, depositAmount); - yield chai_1.expect(taskTreasury.connect(user).depositFunds(userAddress, DAI, depositAmount)) - .to.emit(taskTreasury, "FundsDeposited") - .withArgs(userAddress, DAI_CHECKSUM, depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eq(ethers.utils.parseEther("1")); - yield chai_1.expect(taskTreasury.connect(user).withdrawFunds(userAddress, DAI, depositAmount)) - .to.emit(taskTreasury, "FundsWithdrawn") - .withArgs(userAddress, userAddress, DAI_CHECKSUM, depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eq(ethers.BigNumber.from("0")); - })); - it("user withdraw more ETH than balance", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("10"); - yield taskTreasury - .connect(user2) - .depositFunds(user2Address, ETH, depositAmount, { value: depositAmount }); - const balanceBefore = yield ethers.provider.getBalance(ops.address); - yield taskTreasury - .connect(user) - .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1")); - const balanceAfter = yield ethers.provider.getBalance(ops.address); - chai_1.expect(balanceAfter).to.be.eql(balanceBefore); - chai_1.expect(yield taskTreasury.userTokenBalance(user2Address, ETH)).to.be.eql(depositAmount); - chai_1.expect(Number(yield taskTreasury.userTokenBalance(userAddress, ETH))).to.be.eql(0); - })); - it("user withdraw more DAI than balance", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("10"); - yield helpers_1.getTokenFromFaucet(DAI, user2Address, depositAmount); - yield dai.connect(user2).approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user2) - .depositFunds(user2Address, DAI, depositAmount); - const balanceBefore = yield dai.balanceOf(taskTreasury.address); - yield taskTreasury - .connect(user) - .withdrawFunds(userAddress, DAI, ethers.utils.parseEther("1")); - const balanceAfter = yield dai.balanceOf(taskTreasury.address); - chai_1.expect(balanceAfter).to.be.eql(balanceBefore); - chai_1.expect(yield taskTreasury.userTokenBalance(user2Address, DAI)).to.be.eql(depositAmount); - chai_1.expect(Number(yield taskTreasury.userTokenBalance(userAddress, DAI))).to.be.eql(0); - })); - it("no task found when exec", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - yield ops.connect(user).cancelTask(taskHash); - const [, execData] = yield counterResolver.checker(); - yield chai_1.expect(ops - .connect(diamondSigner) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, true, resolverHash, counter.address, execData)).to.be.revertedWith("Ops: exec: No task found"); - })); - it("canExec should be true, caller does not have enough ETH", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("0.5"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - yield chai_1.expect(ops - .connect(diamondSigner) - .exec(ethers.utils.parseEther("1"), ETH, userAddress, true, resolverHash, counter.address, execData)).to.be.reverted; - })); - it("canExec should be true, caller does not have enough DAI", () => __awaiter(this, void 0, void 0, function* () { - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - const depositAmount = ethers.utils.parseEther("0.5"); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.connect(user).approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, DAI, depositAmount); - yield chai_1.expect(ops - .connect(diamondSigner) - .exec(ethers.utils.parseEther("1"), DAI, userAddress, true, resolverHash, counter.address, execData)).to.be.reverted; - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eql(depositAmount); - })); - it("should exec and pay with ETH", () => __awaiter(this, void 0, void 0, function* () { - const txFee = ethers.utils.parseEther("1"); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("0")); - const depositAmount = ethers.utils.parseEther("2"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - chai_1.expect(yield taskTreasury.connect(user).userTokenBalance(userAddress, ETH)).to.be.eq(depositAmount); - yield ops - .connect(diamondSigner) - .exec(txFee, ETH, userAddress, true, resolverHash, counter.address, execData); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - chai_1.expect(yield taskTreasury.connect(user).userTokenBalance(userAddress, ETH)).to.be.eq(depositAmount.sub(txFee)); - // time not elapsed - yield chai_1.expect(simulateExec(txFee, ETH, userAddress, true, resolverHash, counter.address, execData)).to.be.revertedWith("Ops.exec:Counter: increaseCount: Time not elapsed"); - })); - it("should exec and pay with DAI", () => __awaiter(this, void 0, void 0, function* () { - const txFee = ethers.utils.parseEther("1"); - const [canExec, execData] = yield counterResolver.checker(); - chai_1.expect(canExec).to.be.eq(true); - const THREE_MIN = 3 * 60; - yield hre.network.provider.send("evm_increaseTime", [THREE_MIN]); - yield hre.network.provider.send("evm_mine", []); - const depositAmount = ethers.utils.parseEther("2"); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.connect(user).approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, DAI, depositAmount); - chai_1.expect(yield taskTreasury.connect(user).userTokenBalance(userAddress, DAI)).to.be.eq(depositAmount); - yield ops - .connect(diamondSigner) - .exec(txFee, DAI, userAddress, true, resolverHash, counter.address, execData); - chai_1.expect(yield counter.count()).to.be.eq(ethers.BigNumber.from("100")); - // time not elapsed - yield chai_1.expect(simulateExec(txFee, DAI, userAddress, true, resolverHash, counter.address, execData)).to.be.revertedWith("Ops.exec:Counter: increaseCount: Time not elapsed"); - })); - it("should exec and charge user even when it reverts", () => __awaiter(this, void 0, void 0, function* () { - const txFee = ethers.utils.parseEther("1"); - const [, execData] = yield counterResolver.checker(); - const depositAmount = ethers.utils.parseEther("2"); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - // execute twice in a row - yield ops - .connect(diamondSigner) - .exec(txFee, ETH, userAddress, true, resolverHash, counter.address, execData); - const count = yield counter.count(); - chai_1.expect(count).to.be.eq(ethers.BigNumber.from("100")); - yield ops - .connect(diamondSigner) - .exec(txFee, ETH, userAddress, true, resolverHash, counter.address, execData); - chai_1.expect(yield counter.count()).to.be.eq(count); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq(ethers.BigNumber.from("0")); - })); - it("getTaskIdsByUser test", () => __awaiter(this, void 0, void 0, function* () { - // fake task - yield ops - .connect(user) - .createTask(userAddress, selector, counterResolver.address, resolverData); - const ids = yield ops.getTaskIdsByUser(userAddress); - chai_1.expect(ids.length).to.be.eql(2); - })); - it("getCreditTokensByUser test", () => __awaiter(this, void 0, void 0, function* () { - const depositAmount = ethers.utils.parseEther("1"); - yield helpers_1.getTokenFromFaucet(DAI, userAddress, depositAmount); - yield dai.approve(taskTreasury.address, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, DAI, depositAmount); - yield taskTreasury - .connect(user) - .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql(depositAmount); - chai_1.expect(yield taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eql(depositAmount); - })); - const simulateExec = (_txFee, _feeToken, _taskCreator, _useTaskTreasury, _resolverHash, _execAddress, _execData) => __awaiter(this, void 0, void 0, function* () { - const ZERO = ethers.constants.AddressZero; - yield hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [ZERO], - }); - const mockProvider = yield ethers.getSigner(ZERO); - yield diamond.connect(owner).addExecutors([ZERO]); - const pokeMeData = ops.interface.encodeFunctionData("exec", [ - _txFee, - _feeToken, - _taskCreator, - _useTaskTreasury, - _resolverHash, - _execAddress, - _execData, - ]); - const execData = diamond.interface.encodeFunctionData("exec", [ - ops.address, - pokeMeData, - _feeToken, - ]); - yield mockProvider.call({ to: diamondAddress, data: execData }); - }); -}); diff --git a/dist/test/abis/MegaPoker.json b/dist/test/abis/MegaPoker.json deleted file mode 100644 index 97ab5991..00000000 --- a/dist/test/abis/MegaPoker.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "inputs": [], - "name": "poke", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] diff --git a/dist/test/helpers.js b/dist/test/helpers.js deleted file mode 100644 index 55a18bee..00000000 --- a/dist/test/helpers.js +++ /dev/null @@ -1,77 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getTokenFromFaucet = void 0; -const hardhat_1 = require("hardhat"); -const getTokenFromFaucet = (tokenAddress, recepient, amount) => __awaiter(void 0, void 0, void 0, function* () { - // Fetch actual Faucet - const faucet = getFaucetByToken(tokenAddress.toLowerCase()); - if (!faucet) - throw Error("Faucet not found"); - const faucetEthBalance = yield (yield hardhat_1.ethers.provider.getSigner(faucet)).getBalance(); - const oneEth = hardhat_1.ethers.utils.parseEther("1"); - // Pre-fund faucet account with ETH to pay for tx fee - if (faucet !== getFaucetByToken("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") && - faucetEthBalance.lt(oneEth)) { - // Fund faucet account with ETH - const ethFaucet = getFaucetByToken("0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); - yield hardhat_1.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [ethFaucet], - }); - const ethFaucetSigner = yield hardhat_1.ethers.provider.getSigner(ethFaucet); - const ethSignerBalance = yield ethFaucetSigner.getBalance(); - if (ethSignerBalance.lt(oneEth)) - throw Error(`ETH Faucet has insufficient: ${tokenAddress}`); - const ethTx = yield ethFaucetSigner.sendTransaction({ - to: faucet, - value: oneEth, - }); - yield ethTx.wait(); - } - yield hardhat_1.network.provider.request({ - method: "hardhat_impersonateAccount", - params: [faucet], - }); - const faucetSigner = yield hardhat_1.ethers.provider.getSigner(faucet); - const token = yield hardhat_1.ethers.getContractAt([ - "function transfer(address _recepient, uint256 _amount) public", - "function balanceOf(address _account) view returns(uint256)", - ], tokenAddress, faucetSigner); - const signerBalance = yield token.balanceOf(faucet); - if (signerBalance.lt(amount)) - throw Error(`Faucet has insufficient: ${tokenAddress}`); - const tx = yield token.connect(faucetSigner).transfer(recepient, amount); - yield tx.wait(); - const recepientBalance = yield token.balanceOf(recepient); - if (recepientBalance.lt(amount)) - throw Error(`Tranfer not succesfull: ${tokenAddress}`); -}); -exports.getTokenFromFaucet = getTokenFromFaucet; -// @dev Faucet addresses must have payable fallback function -const getFaucetByToken = (tokenAddress) => { - switch (tokenAddress) { - case "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee": - return "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"; - case "0x6b175474e89094c44da98b954eedeac495271d0f": - return "0x47ac0fb4f2d84898e4d9e7b4dab3c24507a6d503"; - case "0xdd974d5c2e2928dea5f71b9825b8b646686bd200": - return "0x3EB01B3391EA15CE752d01Cf3D3F09deC596F650"; - case "0x6810e776880c02933d47db1b9fc05908e5386b96": - return "0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98"; - case "0x221657776846890989a759ba2973e427dff5c9bb": - return "0x78D196056E1F369Ec2d563aAac504EA53462B30e"; - case "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": - return "0xc247722ac42b2f9ba752886502c3d3dd39bdb2da"; - default: - throw Error("No facet found"); - } -}; diff --git a/hardhat.config.ts b/hardhat.config.ts index 0756c3c6..0d2864ac 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -14,7 +14,6 @@ dotenv.config({ path: __dirname + "/.env" }); // Libraries import assert from "assert"; -import { utils } from "ethers"; // @dev Put this in .env const ALCHEMY_ID = process.env.ALCHEMY_ID; @@ -45,7 +44,7 @@ const config: HardhatUserConfig = { // timeout: 150000, forking: { url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - blockNumber: 12901600, + blockNumber: 14068500, }, }, arbitrum: { @@ -67,7 +66,6 @@ const config: HardhatUserConfig = { accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], chainId: 250, url: `https://rpcapi.fantom.network/`, - gasPrice: parseInt(utils.parseUnits("80", "gwei").toString()), }, gnosis: { url: "https://rpc.gnosischain.com", @@ -78,36 +76,37 @@ const config: HardhatUserConfig = { accounts: DEPLOYER_PK_ROPSTEN ? [DEPLOYER_PK_ROPSTEN] : [], chainId: 5, url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(utils.parseUnits("7", "gwei").toString()), }, mainnet: { accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], chainId: 1, url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(utils.parseUnits("100", "gwei").toString()), }, matic: { url: `https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`, + chainId: 137, + accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], + }, + mumbai: { + url: `https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_ID}`, + chainId: 80001, accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], - gasPrice: parseInt(utils.parseUnits("30", "gwei").toString()), }, rinkeby: { accounts: DEPLOYER_PK_MAINNET ? [DEPLOYER_PK_MAINNET] : [], chainId: 4, url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(utils.parseUnits("7", "gwei").toString()), }, ropsten: { accounts: DEPLOYER_PK_ROPSTEN ? [DEPLOYER_PK_ROPSTEN] : [], chainId: 3, url: `https://eth-ropsten.alchemyapi.io/v2/${ALCHEMY_ID}`, - gasPrice: parseInt(utils.parseUnits("7", "gwei").toString()), }, }, solidity: { compilers: [ { - version: "0.8.0", + version: "0.8.12", }, ], }, diff --git a/hardhat/config/addresses.ts b/hardhat/config/addresses.ts index 0b20283c..fa07e846 100644 --- a/hardhat/config/addresses.ts +++ b/hardhat/config/addresses.ts @@ -2,9 +2,6 @@ export const getGelatoAddress = (network: string): string | undefined => { const GELATO_MAINNET = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; - const GELATO_ROPSTEN = "0xCc4CcD69D31F9FfDBD3BFfDe49c6aA886DaB98d9"; - const GELATO_RINKEBY = "0x0630d1b8C2df3F0a68Df578D02075027a6397173"; - const GELATO_GOERLI = "0x683913B3A32ada4F8100458A3E1675425BdAa7DF"; const GELATO_MATIC = "0x7598e84B2E114AB62CAB288CE5f7d5f6bad35BbA"; const GELATO_FANTOM = "0xebA27A2301975FF5BF7864b99F55A4f7A457ED10"; const GELATO_AVALANCHE = "0x7C5c4Af1618220C090A6863175de47afb20fa9Df"; @@ -12,6 +9,11 @@ export const getGelatoAddress = (network: string): string | undefined => { const GELATO_BSC = "0x7C5c4Af1618220C090A6863175de47afb20fa9Df"; const GELATO_GNOSIS = "0x29b6603D17B9D8f021EcB8845B6FD06E1Adf89DE"; + const GELATO_ROPSTEN = "0xCc4CcD69D31F9FfDBD3BFfDe49c6aA886DaB98d9"; + const GELATO_RINKEBY = "0x0630d1b8C2df3F0a68Df578D02075027a6397173"; + const GELATO_GOERLI = "0x683913B3A32ada4F8100458A3E1675425BdAa7DF"; + const GELATO_MUMBAI = "0x25aD59adbe00C2d80c86d01e2E05e1294DA84823"; + switch (network) { case "mainnet": return GELATO_MAINNET; @@ -33,9 +35,57 @@ export const getGelatoAddress = (network: string): string | undefined => { return GELATO_BSC; case "gnosis": return GELATO_GNOSIS; + case "mumbai": + return GELATO_MUMBAI; case "hardhat": return GELATO_MAINNET; default: - throw new Error("Gelato contract address not found"); + throw new Error("No gelato address for network"); + } +}; + +export const getOldTaskTreasuryAddress = ( + network: string +): string | undefined => { + const TREASURY_MAINNET = "0x66e2F69df68C8F56837142bE2E8C290EfE76DA9f"; + const TREASURY_MATIC = "0xA8a7BBe83960B29789d5CB06Dcd2e6C1DF20581C"; + const TREASURY_FANTOM = "0x6c3224f9b3feE000A444681d5D45e4532D5BA531"; + const TREASURY_AVALANCHE = "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb"; + const TREASURY_ARBITRUM = "0x527a819db1eb0e34426297b03bae11F2f8B3A19E"; + const TREASURY_BSC = "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb"; + const TREASURY_GNOSIS = "0x95f4538C3950CE0EF5821f2049aE2aC5cCade68D"; + + const TREASURY_ROPSTEN = "0x2705aCca70CdB3E326C1013eEA2c03A4f2935b66"; + const TREASURY_RINKEBY = "0x90F609c73F7498dD031e0dAfF3B40e93c04a6C60"; + const TREASURY_GOERLI = "0xA0Cc0CC82d945D96D4F481A62C968AfCCea1C54F"; + const TREASURY_MUMBAI = "0x63C51b1D80B209Cf336Bec5a3E17D3523B088cdb"; + + switch (network) { + case "mainnet": + return TREASURY_MAINNET; + case "ropsten": + return TREASURY_ROPSTEN; + case "rinkeby": + return TREASURY_RINKEBY; + case "goerli": + return TREASURY_GOERLI; + case "matic": + return TREASURY_MATIC; + case "fantom": + return TREASURY_FANTOM; + case "avalanche": + return TREASURY_AVALANCHE; + case "arbitrum": + return TREASURY_ARBITRUM; + case "bsc": + return TREASURY_BSC; + case "gnosis": + return TREASURY_GNOSIS; + case "mumbai": + return TREASURY_MUMBAI; + case "hardhat": + return TREASURY_MAINNET; + default: + throw new Error("No old task treasury address for network"); } }; diff --git a/hardhat/config/maxFee.ts b/hardhat/config/maxFee.ts new file mode 100644 index 00000000..c4bfe769 --- /dev/null +++ b/hardhat/config/maxFee.ts @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { BigNumber } from "ethers"; +import { ethers } from "hardhat"; + +export const getMaxFee = (network: string): BigNumber | undefined => { + switch (network) { + case "mainnet": + return ethers.utils.parseEther("0"); + case "ropsten": + return ethers.utils.parseEther("0"); + case "rinkeby": + return ethers.utils.parseEther("0"); + case "goerli": + return ethers.utils.parseEther("0"); + case "matic": + return ethers.utils.parseEther("5"); + case "fantom": + return ethers.utils.parseEther("50"); + case "avalanche": + return ethers.utils.parseEther("2"); + case "arbitrum": + return ethers.utils.parseEther("0.01"); + case "bsc": + return ethers.utils.parseEther("0.01"); + case "gnosis": + return ethers.utils.parseEther("2"); + case "mumbai": + return ethers.utils.parseEther("0"); + case "hardhat": + return ethers.utils.parseEther("100"); + default: + throw new Error("No maxFee for network"); + } +}; diff --git a/package.json b/package.json index 460d9e7c..98dc0ed3 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers", "@nomiclabs/hardhat-etherscan": "^2.1.4", "@nomiclabs/hardhat-waffle": "^2.0.1", - "@openzeppelin/contracts": "^4.2.0", + "@openzeppelin/contracts": "^4.5.0", + "@openzeppelin/contracts-upgradeable": "^4.4.2", "@tsconfig/recommended": "1.0.1", "@typechain/ethers-v5": "7.0.1", "@typechain/hardhat": "2.2.0", @@ -45,7 +46,7 @@ "ethereum-waffle": "^3.4.0", "ethers": "^5.4.2", "hardhat": "^2.4.3", - "hardhat-deploy": "^0.9.0", + "hardhat-deploy": "^0.11.4", "hardhat-deploy-ethers": "^0.3.0-beta.10", "hardhat-gas-reporter": "^1.0.4", "husky": "7.0.1", diff --git a/test/Ops-WithoutTreasury.test.ts b/test/Ops-WithoutTreasury.test.ts index 26e383cc..2e6c05d0 100644 --- a/test/Ops-WithoutTreasury.test.ts +++ b/test/Ops-WithoutTreasury.test.ts @@ -12,7 +12,6 @@ import { Ops, CounterWithoutTreasury, CounterResolverWithoutTreasury, - TaskTreasury, IERC20, } from "../typechain"; @@ -20,7 +19,7 @@ describe("Ops without treasury test", function () { let ops: Ops; let counter: CounterWithoutTreasury; let counterResolver: CounterResolverWithoutTreasury; - let taskTreasury: TaskTreasury; + let dai: IERC20; let user: Signer; @@ -43,7 +42,6 @@ describe("Ops without treasury test", function () { userAddress = await user.getAddress(); ops = await ethers.getContract("Ops"); - taskTreasury = await ethers.getContract("TaskTreasury"); counter = ( await ethers.getContract("CounterWithoutTreasury") ); @@ -54,8 +52,6 @@ describe("Ops without treasury test", function () { executorAddress = gelatoAddress; - await taskTreasury.addWhitelistedService(ops.address); - await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [executorAddress], diff --git a/test/Ops-createTimedTask.test.ts b/test/Ops-createTimedTask.test.ts index e2dbc406..28580e4a 100644 --- a/test/Ops-createTimedTask.test.ts +++ b/test/Ops-createTimedTask.test.ts @@ -3,7 +3,12 @@ import { Signer } from "@ethersproject/abstract-signer"; import { expect } from "chai"; import hre = require("hardhat"); const { ethers, deployments } = hre; -import { Ops, TaskTreasury, Forwarder, CounterTimedTask } from "../typechain"; +import { + Ops, + TaskTreasuryUpgradable, + Forwarder, + CounterTimedTask, +} from "../typechain"; const gelatoAddress = "0x3caca7b48d0573d793d3b0279b5f0029180e83b6"; const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; @@ -15,7 +20,7 @@ describe("Ops createTimedTask test", function () { let ops: Ops; - let taskTreasury: TaskTreasury; + let taskTreasury: TaskTreasuryUpgradable; let forwarder: Forwarder; let counter: CounterTimedTask; @@ -37,17 +42,18 @@ describe("Ops createTimedTask test", function () { before(async function () { await deployments.fixture(); - [user] = await ethers.getSigners(); + [, user] = await ethers.getSigners(); userAddress = await user.getAddress(); ops = await ethers.getContract("Ops"); - taskTreasury = await ethers.getContract("TaskTreasury"); + taskTreasury = await ethers.getContract("TaskTreasuryUpgradable"); + counter = await ethers.getContract("CounterTimedTask"); forwarder = await ethers.getContract("Forwarder"); executorAddress = gelatoAddress; - await taskTreasury.addWhitelistedService(ops.address); + await taskTreasury.updateWhitelistedService(ops.address, true); const depositAmount = ethers.utils.parseEther("1"); await taskTreasury @@ -157,7 +163,7 @@ describe("Ops createTimedTask test", function () { ETH, userAddress, true, - false, + true, resolverHash, execAddress, execData diff --git a/test/Ops.test.ts b/test/Ops.test.ts index d4527529..c8688262 100644 --- a/test/Ops.test.ts +++ b/test/Ops.test.ts @@ -7,8 +7,8 @@ import { Ops, Counter, CounterResolver, - TaskTreasury, IERC20, + TaskTreasuryUpgradable, } from "../typechain"; import { BigNumber } from "ethereum-waffle/node_modules/ethers"; @@ -20,7 +20,7 @@ describe("Ops test", function () { let ops: Ops; let counter: Counter; let counterResolver: CounterResolver; - let taskTreasury: TaskTreasury; + let taskTreasury: TaskTreasuryUpgradable; let dai: IERC20; let user: Signer; @@ -39,19 +39,21 @@ describe("Ops test", function () { beforeEach(async function () { await deployments.fixture(); - [user, user2] = await hre.ethers.getSigners(); + [, user, user2] = await hre.ethers.getSigners(); userAddress = await user.getAddress(); user2Address = await user2.getAddress(); ops = await ethers.getContract("Ops"); - taskTreasury = await ethers.getContract("TaskTreasury"); + taskTreasury = ( + await ethers.getContract("TaskTreasuryUpgradable") + ); counter = await ethers.getContract("Counter"); counterResolver = ( await ethers.getContract("CounterResolver") ); dai = await ethers.getContractAt("IERC20", DAI); - await taskTreasury.addWhitelistedService(ops.address); + await taskTreasury.updateWhitelistedService(ops.address, true); await hre.network.provider.request({ method: "hardhat_impersonateAccount", @@ -126,36 +128,36 @@ describe("Ops test", function () { }); it("deposit and withdraw ETH", async () => { - const depositAmount = ethers.utils.parseEther("1"); + const depositAmount = ethers.utils.parseEther("2"); + const withdrawAmount = ethers.utils.parseEther("1"); await taskTreasury .connect(user) .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); expect(await taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq( - ethers.utils.parseEther("1") + depositAmount ); await expect( - taskTreasury - .connect(user) - .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1")) + taskTreasury.connect(user).withdrawFunds(userAddress, ETH, withdrawAmount) ) .to.emit(taskTreasury, "FundsWithdrawn") - .withArgs(userAddress, userAddress, ETH, depositAmount); + .withArgs(userAddress, userAddress, ETH, withdrawAmount); - expect(await taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eq( - ethers.BigNumber.from("0") + expect(await taskTreasury.userTokenBalance(userAddress, ETH)).to.be.eql( + depositAmount.sub(withdrawAmount) ); }); it("deposit and withdraw DAI", async () => { - const depositAmount = ethers.utils.parseEther("1"); + const depositAmount = ethers.utils.parseEther("2"); + const withdrawAmount = ethers.utils.parseEther("1"); const DAI_CHECKSUM = ethers.utils.getAddress(DAI); await getTokenFromFaucet(DAI, userAddress, depositAmount); - await dai.approve(taskTreasury.address, depositAmount); + await dai.connect(user).approve(taskTreasury.address, depositAmount); await expect( taskTreasury.connect(user).depositFunds(userAddress, DAI, depositAmount) ) @@ -163,17 +165,17 @@ describe("Ops test", function () { .withArgs(userAddress, DAI_CHECKSUM, depositAmount); expect(await taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eq( - ethers.utils.parseEther("1") + depositAmount ); await expect( - taskTreasury.connect(user).withdrawFunds(userAddress, DAI, depositAmount) + taskTreasury.connect(user).withdrawFunds(userAddress, DAI, withdrawAmount) ) .to.emit(taskTreasury, "FundsWithdrawn") - .withArgs(userAddress, userAddress, DAI_CHECKSUM, depositAmount); + .withArgs(userAddress, userAddress, DAI_CHECKSUM, withdrawAmount); - expect(await taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eq( - ethers.BigNumber.from("0") + expect(await taskTreasury.userTokenBalance(userAddress, DAI)).to.be.eql( + depositAmount.sub(withdrawAmount) ); }); @@ -186,9 +188,11 @@ describe("Ops test", function () { const balanceBefore = await ethers.provider.getBalance(ops.address); - await taskTreasury - .connect(user) - .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1")); + await expect( + taskTreasury + .connect(user) + .withdrawFunds(userAddress, ETH, ethers.utils.parseEther("1")) + ).to.be.reverted; const balanceAfter = await ethers.provider.getBalance(ops.address); @@ -213,9 +217,11 @@ describe("Ops test", function () { const balanceBefore = await dai.balanceOf(taskTreasury.address); - await taskTreasury - .connect(user) - .withdrawFunds(userAddress, DAI, ethers.utils.parseEther("1")); + await expect( + taskTreasury + .connect(user) + .withdrawFunds(userAddress, DAI, ethers.utils.parseEther("1")) + ).to.be.reverted; const balanceAfter = await dai.balanceOf(taskTreasury.address); @@ -484,7 +490,7 @@ describe("Ops test", function () { await getTokenFromFaucet(DAI, userAddress, depositAmount); - await dai.approve(taskTreasury.address, depositAmount); + await dai.connect(user).approve(taskTreasury.address, depositAmount); await taskTreasury .connect(user) diff --git a/test/TaskTreasuryUpgradable.test.ts b/test/TaskTreasuryUpgradable.test.ts new file mode 100644 index 00000000..6ac1ec81 --- /dev/null +++ b/test/TaskTreasuryUpgradable.test.ts @@ -0,0 +1,473 @@ +import { expect } from "chai"; +import { Signer } from "@ethersproject/abstract-signer"; +import { abi as EIP173PROXY_ABI } from "hardhat-deploy/extendedArtifacts/EIP173Proxy.json"; +import { BigNumber } from "ethereum-waffle/node_modules/ethers"; +import { getTokenFromFaucet } from "./helpers"; +import { + IERC20, + Counter, + Ops, + TaskTreasury, + TaskTreasuryUpgradable, +} from "../typechain"; + +import hre = require("hardhat"); +const { ethers, deployments } = hre; + +const GELATO = "0x3CACa7b48D0573D793d3b0279b5F0029180E83b6"; +const OPS_173PROXY = "0xB3f5503f93d5Ef84b06993a1975B9D21B962892F"; +const OLD_TASK_TREASURY = "0x66e2F69df68C8F56837142bE2E8C290EfE76DA9f"; +const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; +const DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; +const WBTC = "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"; + +describe("TaskTreasuryUpgradable test", function () { + this.timeout(0); + + let deployer: Signer; + let deployerAddress: string; + + let user: Signer; + let userAddress: string; + + let user2: Signer; + let user2Address: string; + + let executor: Signer; + + let ops: Ops; + let oldTreasury: TaskTreasury; + let treasury: TaskTreasuryUpgradable; + let counter: Counter; + let dai: IERC20; + let wbtc: IERC20; + + let execData: string; + let execAddress: string; + let resolverHash: string; + + beforeEach(async function () { + await deployments.fixture(); + [deployer, user, user2] = await ethers.getSigners(); + deployerAddress = await deployer.getAddress(); + userAddress = await user.getAddress(); + user2Address = await user2.getAddress(); + + oldTreasury = await ethers.getContractAt("TaskTreasury", OLD_TASK_TREASURY); + treasury = await ethers.getContract("TaskTreasuryUpgradable"); + dai = await ethers.getContractAt("IERC20", DAI); + wbtc = await ethers.getContractAt("IERC20", WBTC); + + const counterFactory = await ethers.getContractFactory("Counter"); + counter = await counterFactory.deploy(OPS_173PROXY); + + const opsFactory = await ethers.getContractFactory("Ops"); + const opsImplementation = await opsFactory.deploy(GELATO, treasury.address); + const ops173Proxy = await ethers.getContractAt( + EIP173PROXY_ABI, + OPS_173PROXY + ); + + // get accounts + const treasuryOwnerAddress = await oldTreasury.owner(); + const opsOwnerAddress = await ops173Proxy.owner(); + + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [treasuryOwnerAddress], + }); + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [opsOwnerAddress], + }); + await hre.network.provider.request({ + method: "hardhat_impersonateAccount", + params: [GELATO], + }); + + executor = await ethers.getSigner(GELATO); + const treasuryOwner = await ethers.getSigner(treasuryOwnerAddress); + const opsOwner = await ethers.getSigner(opsOwnerAddress); + + // account set-up + const value = ethers.utils.parseEther("100"); + const wbtcValue = ethers.utils.parseUnits("0.5", "gwei"); // 2WBTC + await getTokenFromFaucet(DAI, userAddress, value); + await getTokenFromFaucet(DAI, user2Address, value); + await getTokenFromFaucet(WBTC, userAddress, wbtcValue); + await getTokenFromFaucet(WBTC, user2Address, wbtcValue); + + await deployer.sendTransaction({ + to: treasuryOwnerAddress, + value, + }); + + // upgrade opsProxy + await ops173Proxy.connect(opsOwner).upgradeTo(opsImplementation.address); + ops = await ethers.getContractAt("Ops", OPS_173PROXY); + + // whitelist + oldTreasury.connect(treasuryOwner).addWhitelistedService(treasury.address); + treasury.connect(deployer).updateWhitelistedService(ops.address, true); + + // create task + const execSelector = counter.interface.getSighash("increaseCount"); + execAddress = counter.address; + execData = counter.interface.encodeFunctionData("increaseCount", [1]); + + const resolverAddress = ethers.constants.AddressZero; + const resolverData = ethers.constants.HashZero; + resolverHash = await ops.getResolverHash(resolverAddress, resolverData); + + await ops + .connect(user) + .createTask(execAddress, execSelector, resolverAddress, resolverData); + }); + + it("ops proxy should have correct treasury address", async () => { + expect(await ops.taskTreasury()).to.be.eql(treasury.address); + }); + + it("maxFee should be correct", async () => { + expect(await treasury.maxFee()).to.be.eql(ethers.utils.parseEther("100")); + }); + + it("deposit ETH", async () => { + const depositAmount = ethers.utils.parseEther("5"); + + await depositEth(user, depositAmount); + }); + + it("deposit DAI", async () => { + const depositAmount = ethers.utils.parseEther("5"); + + await depositErc20(user, DAI, depositAmount); + }); + + it("deposit WBTC", async () => { + const depositAmount = ethers.utils.parseUnits("0.1", "gwei"); + + await depositErc20(user, WBTC, depositAmount); + }); + + it("first deposit less than MIN_SHARES_IN_TREASURY", async () => { + const depositAmount = ethers.BigNumber.from("1"); + + await expect(depositEth(user, depositAmount)).to.be.revertedWith( + "TaskTreasury: Require MIN_SHARES_IN_TREASURY" + ); + await expect(depositErc20(user, DAI, depositAmount)).to.be.revertedWith( + "TaskTreasury: Require MIN_SHARES_IN_TREASURY" + ); + }); + + it("multiple users deposit ETH", async () => { + const depositAmount1 = ethers.utils.parseEther("2"); + const depositAmount2 = ethers.utils.parseEther("4"); + + await depositEth(user, depositAmount1); + await depositEth(user2, depositAmount2); + }); + + it("multiple users deposit DAI", async () => { + const depositAmount1 = ethers.utils.parseEther("2"); + const depositAmount2 = ethers.utils.parseEther("3"); + + await depositErc20(user, DAI, depositAmount1); + await depositErc20(user2, DAI, depositAmount2); + }); + + it("multiple users deposit WBTC", async () => { + const depositAmount1 = ethers.utils.parseUnits("0.2", "gwei"); + const depositAmount2 = ethers.utils.parseUnits("0.3", "gwei"); + + await depositErc20(user, WBTC, depositAmount1); + await depositErc20(user2, WBTC, depositAmount2); + }); + + it("multiple users deposit then withdraw eth", async () => { + const depositAmount1 = ethers.utils.parseEther("10"); + const depositAmount2 = ethers.utils.parseEther("12"); + + await depositEth(user, depositAmount1); + await depositEth(user2, depositAmount2); + + const withdrawAmount = ethers.utils.parseEther("3"); + + await withdraw(user, "eth", withdrawAmount); + await withdraw(user2, "eth", withdrawAmount); + }); + + it("multiple users deposit then withdraw dai", async () => { + const depositAmount1 = ethers.utils.parseEther("10"); + const depositAmount2 = ethers.utils.parseEther("12"); + + await depositErc20(user, DAI, depositAmount1); + await depositErc20(user2, DAI, depositAmount2); + + const withdrawAmount = ethers.utils.parseEther("3"); + + await withdraw(user, "dai", withdrawAmount); + await withdraw(user2, "dai", withdrawAmount); + }); + + it("multiple users deposit then withdraw WBTC", async () => { + const depositAmount1 = ethers.utils.parseUnits("0.02", "gwei"); + const depositAmount2 = ethers.utils.parseUnits("0.03", "gwei"); + + await depositErc20(user, WBTC, depositAmount1); + await depositErc20(user2, WBTC, depositAmount2); + + const withdrawAmount = ethers.utils.parseUnits("0.01", "gwei"); + + await withdraw(user, "wbtc", withdrawAmount); + await withdraw(user2, "wbtc", withdrawAmount); + }); + + it("withdraw below MIN_SHARES_IN_TREASURY", async () => { + const depositAmount1 = ethers.utils.parseEther("10"); + const depositAmount2 = ethers.utils.parseUnits("0.2", "gwei"); + const withdrawAmount1 = depositAmount1.sub(10); + const withdrawAmount2 = depositAmount2.sub(10); + + await depositEth(user, depositAmount1); + await expect(withdraw(user, "eth", withdrawAmount1)).to.be.revertedWith( + "TaskTreasury: Below MIN_SHARES_IN_TREASURY" + ); + await depositErc20(user, WBTC, depositAmount2); + await expect(withdraw(user, "wbtc", withdrawAmount2)).to.be.revertedWith( + "TaskTreasury: Below MIN_SHARES_IN_TREASURY" + ); + }); + + it("useFunds in ETH - no funds in old treasury", async () => { + const depositAmount = ethers.utils.parseEther("8"); + const txFee = ethers.utils.parseEther("0.5"); + + await depositEth(user, depositAmount); + + const expectedTreasuryBalance = depositAmount.sub(txFee); + await execute("eth", txFee, expectedTreasuryBalance); + }); + + it("useFunds in ETH - funds in old treasury partially covers txFee", async () => { + const depositAmount = ethers.utils.parseEther("1"); + const txFee = ethers.utils.parseEther("1.5"); + + await depositEth(user, depositAmount); + await depositEth(user2, depositAmount); + await oldTreasury + .connect(user) + .depositFunds(userAddress, ETH, depositAmount, { + value: depositAmount, + }); + + const expectedTreasuryBalance = depositAmount.mul(2).sub(txFee); + await execute("eth", txFee, expectedTreasuryBalance); + }); + + it("useFunds in ETH - funds in old treasury covers txFee", async () => { + const depositAmount = ethers.utils.parseEther("1"); + const txFee = ethers.utils.parseEther("1"); + + await depositEth(user, depositAmount); + await depositEth(user2, depositAmount); + await oldTreasury + .connect(user) + .depositFunds(userAddress, ETH, depositAmount, { + value: depositAmount, + }); + + const expectedTreasuryBalance = depositAmount.mul(2).sub(txFee); + await execute("eth", txFee, expectedTreasuryBalance); + }); + + it("useFunds in DAI - no funds in old treasury", async () => { + const depositAmount = ethers.utils.parseEther("8"); + const txFee = ethers.utils.parseEther("0.5"); + + await depositErc20(user, DAI, depositAmount); + await depositErc20(user2, DAI, depositAmount); + + const expectedTreasuryBalance = depositAmount.sub(txFee); + await execute("dai", txFee, expectedTreasuryBalance); + }); + + it("useFunds in DAI - funds in old treasury partially covers txFee", async () => { + const depositAmount = ethers.utils.parseEther("1"); + const txFee = ethers.utils.parseEther("1.5"); + + await depositErc20(user, DAI, depositAmount); + await depositErc20(user2, DAI, depositAmount); + await dai.connect(user).approve(oldTreasury.address, depositAmount); + await oldTreasury + .connect(user) + .depositFunds(userAddress, DAI, depositAmount); + + const expectedTreasuryBalance = depositAmount.mul(2).sub(txFee); + await execute("dai", txFee, expectedTreasuryBalance); + }); + + it("useFunds in DAI - funds in old treasury covers txFee", async () => { + const depositAmount = ethers.utils.parseEther("1"); + const txFee = ethers.utils.parseEther("1"); + + await depositErc20(user, DAI, depositAmount); + await depositErc20(user2, DAI, depositAmount); + await dai.connect(user).approve(oldTreasury.address, depositAmount); + await oldTreasury + .connect(user) + .depositFunds(userAddress, DAI, depositAmount); + + const expectedTreasuryBalance = depositAmount.mul(2).sub(txFee); + await execute("dai", txFee, expectedTreasuryBalance); + }); + + it("getCreditTokensByUser & totalUserTokenBalance", async () => { + const depositAmount = ethers.utils.parseEther("1"); + const depositAmount2 = ethers.utils.parseUnits("0.2", "gwei"); + + await oldTreasury + .connect(user) + .depositFunds(userAddress, ETH, depositAmount, { value: depositAmount }); + + await dai.connect(user).approve(oldTreasury.address, depositAmount); + await oldTreasury + .connect(user) + .depositFunds(userAddress, DAI, depositAmount); + + await depositEth(user, depositAmount); + await depositErc20(user, DAI, depositAmount); + await depositErc20(user, WBTC, depositAmount2); + + const tokens = await treasury.getTotalCreditTokensByUser(userAddress); + expect(tokens.includes(ETH)).to.be.eql(true); + expect(tokens.includes(DAI)).to.be.eql(true); + expect(tokens.includes(WBTC)).to.be.eql(true); + + const daiTokenBalance = await treasury.totalUserTokenBalance( + userAddress, + DAI + ); + const ethTokenBalance = await treasury.totalUserTokenBalance( + userAddress, + ETH + ); + expect(daiTokenBalance).to.be.eql(depositAmount.mul(2)); + expect(ethTokenBalance).to.be.eql(depositAmount.mul(2)); + }); + + //---------------------------Helper functions------------------------------- + const execute = async ( + token: "eth" | "dai", + txFee: BigNumber, + expectedTreasuryBalance: BigNumber + ) => { + const tokenAddress = token == "eth" ? ETH : DAI; + + await ops + .connect(executor) + .exec( + txFee, + tokenAddress, + userAddress, + true, + true, + resolverHash, + execAddress, + execData + ); + + const balanceAfter = await treasury.userTokenBalance( + userAddress, + tokenAddress + ); + + expect(balanceAfter).to.be.eql(expectedTreasuryBalance); + }; + + const depositEth = async (signer: Signer, depositAmount: BigNumber) => { + const signerAddress = await signer.getAddress(); + const balanceBefore = await treasury.userTokenBalance(signerAddress, ETH); + const value = depositAmount.div(2); + + await treasury.connect(signer).depositFunds(signerAddress, ETH, value, { + value, + }); + await signer.sendTransaction({ + to: treasury.address, + value, + }); + + const balanceAfter = await treasury.userTokenBalance(signerAddress, ETH); + + expect(balanceAfter).to.be.eql(balanceBefore.add(depositAmount)); + }; + + const depositErc20 = async ( + signer: Signer, + tokenAddress: string, + depositAmount: BigNumber + ) => { + const signerAddress = await signer.getAddress(); + const balanceBefore = await treasury.userTokenBalance( + signerAddress, + tokenAddress + ); + + const erc20 = await ethers.getContractAt("IERC20", tokenAddress); + await erc20.connect(signer).approve(treasury.address, depositAmount); + await treasury + .connect(signer) + .depositFunds(signerAddress, tokenAddress, depositAmount); + + const balanceAfter = await treasury.userTokenBalance( + signerAddress, + tokenAddress + ); + + expect(balanceAfter).to.be.eql(balanceBefore.add(depositAmount)); + }; + + const withdraw = async ( + signer: Signer, + token: "eth" | "dai" | "wbtc", + withdrawAmount: BigNumber + ) => { + const signerAddress = await signer.getAddress(); + const tokenAddress = token == "eth" ? ETH : token == "dai" ? DAI : WBTC; + + const treasuryBalanceBefore = await treasury.userTokenBalance( + signerAddress, + tokenAddress + ); + const balanceBefore = await getBalance(deployerAddress, token); + + // withdraw to deployer to compare ETH balance change accurately, ignoring gas cost + await treasury + .connect(signer) + .withdrawFunds(deployerAddress, tokenAddress, withdrawAmount); + + const treasuryBalanceAfter = await treasury.userTokenBalance( + signerAddress, + tokenAddress + ); + const balanceAfter = await getBalance(deployerAddress, token); + + expect(treasuryBalanceAfter).to.be.eql( + treasuryBalanceBefore.sub(withdrawAmount) + ); + expect(balanceAfter).to.be.eql(balanceBefore.add(withdrawAmount)); + }; + + const getBalance = async ( + address: string, + token: "eth" | "dai" | "wbtc" + ): Promise => { + if (token == "eth") { + return await ethers.provider.getBalance(address); + } else if (token == "dai") { + return await dai.balanceOf(address); + } else return await wbtc.balanceOf(address); + }; +}); diff --git a/test/helpers.ts b/test/helpers.ts index 8df7ece6..4718ad3a 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -85,7 +85,11 @@ const getFaucetByToken = (tokenAddress: string): string => { case "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": return "0xc247722ac42b2f9ba752886502c3d3dd39bdb2da"; + + case "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599": + return "0xe78388b4ce79068e89bf8aa7f218ef6b9ab0e9d0"; + default: - throw Error("No facet found"); + throw Error("No faucet found"); } }; diff --git a/yarn.lock b/yarn.lock index e9897f5a..bf06b36f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -670,15 +670,20 @@ "@types/sinon-chai" "^3.2.3" "@types/web3" "1.0.19" +"@openzeppelin/contracts-upgradeable@^4.4.2": + version "4.4.2" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.4.2.tgz#748a5986a02548ef541cabc2ce8c67a890044c40" + integrity sha512-bavxs18L47EmcdnL9I6DzsVSUJO+0/zD6zH7/6qG7QRBugvR3VNVZR+nMvuZlCNwuTTnCa3apR00PYzYr/efAw== + "@openzeppelin/contracts@3.4.1-solc-0.7-2": version "3.4.1-solc-0.7-2" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92" integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q== -"@openzeppelin/contracts@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.2.0.tgz#260d921d99356e48013d9d760caaa6cea35dc642" - integrity sha512-LD4NnkKpHHSMo5z9MvFsG4g1xxZUDqV3A3Futu3nvyfs4wPwXxqOgMaxOoa2PeyGL2VNeSlbxT54enbQzGcgJQ== +"@openzeppelin/contracts@^4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.5.0.tgz#3fd75d57de172b3743cdfc1206883f56430409cc" + integrity sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA== "@resolver-engine/core@^0.3.3": version "0.3.3" @@ -4856,16 +4861,17 @@ hardhat-deploy-ethers@^0.3.0-beta.10: resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.10.tgz#bccfcf635d380bbab3638960f6739fe4d396fc5f" integrity sha512-TeyriUshRZ7XVHOjMsDtTozIrdwLf3Bw+oZRYNhXdG/eut5HeDhjUFPfRlG7TI1lSLvkcB5dt7OxOtPYKDOxTg== -hardhat-deploy@^0.9.0: - version "0.9.1" - resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.9.1.tgz#878bb10ef1bfcfee892477c2133295a250721672" - integrity sha512-GUrLlsBKZqWJ2isFDnpnlnyLuIDqES7mEFGm4P7GutG2jeBebvTg2wCNh3RTW/rpHUtU66yCZXfy+LeD0QXFbg== +hardhat-deploy@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/hardhat-deploy/-/hardhat-deploy-0.11.4.tgz#39b06d3b0ad25195071cc1f2f71649b1f9f030d0" + integrity sha512-BNMwWqaxrwb8XKrYzmCwnUzOSKzicUBk+fwd28doUNoAGFFh8kpoypkcHMzKDVdLhnamAardcfqJet73zrZoTA== dependencies: "@ethersproject/abi" "^5.4.0" "@ethersproject/abstract-signer" "^5.4.1" "@ethersproject/address" "^5.4.0" "@ethersproject/bignumber" "^5.4.1" "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" "@ethersproject/contracts" "^5.4.1" "@ethersproject/providers" "^5.4.4" "@ethersproject/solidity" "^5.4.0"