creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/PercentSplitETH.sol": {
        "content": "/*\n  ･\n   *　★\n      ･ ｡\n        　･　ﾟ☆ ｡\n  　　　 *　★ ﾟ･｡ *  ｡\n          　　* ☆ ｡･ﾟ*.｡\n      　　　ﾟ *.｡☆｡★　･\n​\n                      `                     .-:::::-.`              `-::---...```\n                     `-:`               .:+ssssoooo++//:.`       .-/+shhhhhhhhhhhhhyyyssooo:\n                    .--::.            .+ossso+/////++/:://-`   .////+shhhhhhhhhhhhhhhhhhhhhy\n                  `-----::.         `/+////+++///+++/:--:/+/-  -////+shhhhhhhhhhhhhhhhhhhhhy\n                 `------:::-`      `//-.``.-/+ooosso+:-.-/oso- -////+shhhhhhhhhhhhhhhhhhhhhy\n                .--------:::-`     :+:.`  .-/osyyyyyyso++syhyo.-////+shhhhhhhhhhhhhhhhhhhhhy\n              `-----------:::-.    +o+:-.-:/oyhhhhhhdhhhhhdddy:-////+shhhhhhhhhhhhhhhhhhhhhy\n             .------------::::--  `oys+/::/+shhhhhhhdddddddddy/-////+shhhhhhhhhhhhhhhhhhhhhy\n            .--------------:::::-` +ys+////+yhhhhhhhddddddddhy:-////+yhhhhhhhhhhhhhhhhhhhhhy\n          `----------------::::::-`.ss+/:::+oyhhhhhhhhhhhhhhho`-////+shhhhhhhhhhhhhhhhhhhhhy\n         .------------------:::::::.-so//::/+osyyyhhhhhhhhhys` -////+shhhhhhhhhhhhhhhhhhhhhy\n       `.-------------------::/:::::..+o+////+oosssyyyyyyys+`  .////+shhhhhhhhhhhhhhhhhhhhhy\n       .--------------------::/:::.`   -+o++++++oooosssss/.     `-//+shhhhhhhhhhhhhhhhhhhhyo\n     .-------   ``````.......--`        `-/+ooooosso+/-`          `./++++///:::--...``hhhhyo\n                                              `````\n   *　\n      ･ ｡\n　　　　･　　ﾟ☆ ｡\n  　　　 *　★ ﾟ･｡ *  ｡\n          　　* ☆ ｡･ﾟ*.｡\n      　　　ﾟ *.｡☆｡★　･\n    *　　ﾟ｡·*･｡ ﾟ*\n  　　　☆ﾟ･｡°*. ﾟ\n　 ･ ﾟ*｡･ﾟ★｡\n　　･ *ﾟ｡　　 *\n　･ﾟ*｡★･\n ☆∴｡　*\n･ ｡\n*/\n\n// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/proxy/Clones.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./interfaces/IERC20Approve.sol\";\nimport \"./interfaces/IERC20IncreaseAllowance.sol\";\nimport \"./libraries/BytesLibrary.sol\";\n\n/**\n * @title Auto-forward ETH to a pre-determined list of addresses.\n * @notice Deploys contracts which auto-forwards any ETH sent to it to a list of recipients\n * considering their percent share of the payment received.\n * @dev Uses create2 counterfactual addresses so that the destination is known from the terms of the split.\n */\ncontract PercentSplitETH is Initializable {\n  using AddressUpgradeable for address payable;\n  using AddressUpgradeable for address;\n  using BytesLibrary for bytes;\n  using SafeMath for uint256;\n\n  /// @notice A representation of shares using 16-bits for efficient storage.\n  /// @dev This is only used internally.\n  struct ShareCompressed {\n    address payable recipient;\n    uint16 percentInBasisPoints;\n  }\n\n  /// @notice A representation of shares using 256-bits to ease integration.\n  struct Share {\n    address payable recipient;\n    uint256 percentInBasisPoints;\n  }\n\n  uint256 private constant BASIS_POINTS = 10000;\n\n  ShareCompressed[] private _shares;\n\n  /**\n   * @notice Emitted when a new percent split contract is created from this factory.\n   * @param contractAddress The address of the new percent split contract.\n   */\n  event PercentSplitCreated(address indexed contractAddress);\n  /**\n   * @notice Emitted for each share of the split being defined.\n   * @param recipient The address of the recipient when payment to the split is received.\n   * @param percentInBasisPoints The percent of the payment received by the recipient, in basis points.\n   */\n  event PercentSplitShare(address indexed recipient, uint256 percentInBasisPoints);\n  /**\n   * @notice Emitted when ETH is transferred to a recipient through this split contract.\n   * @param account The account which received payment.\n   * @param amount The amount of ETH payment sent to this recipient.\n   */\n  event ETHTransferred(address indexed account, uint256 amount);\n  /**\n   * @notice Emitted when an ERC20 token is transferred to a recipient through this split contract.\n   * @param erc20Contract The address of the ERC20 token contract.\n   * @param account The account which received payment.\n   * @param amount The amount of ERC20 tokens sent to this recipient.\n   */\n  event ERC20Transferred(address indexed erc20Contract, address indexed account, uint256 amount);\n\n  /**\n   * @dev Requires that the msg.sender is one of the recipients in this split.\n   */\n  modifier onlyRecipient() {\n    for (uint256 i = 0; i < _shares.length; ++i) {\n      if (_shares[i].recipient == msg.sender) {\n        _;\n        return;\n      }\n    }\n    revert(\"Split: Can only be called by one of the recipients\");\n  }\n\n  /**\n   * @notice Creates a new minimal proxy contract and initializes it with the given split terms.\n   * If the contract had already been created, its address is returned.\n   * This must be called on the original implementation and not a proxy created previously.\n   */\n  function createSplit(Share[] memory shares) external returns (PercentSplitETH splitInstance) {\n    bytes32 salt = keccak256(abi.encode(shares));\n    address clone = Clones.predictDeterministicAddress(address(this), salt);\n    splitInstance = PercentSplitETH(payable(clone));\n    if (!clone.isContract()) {\n      emit PercentSplitCreated(clone);\n      Clones.cloneDeterministic(address(this), salt);\n      splitInstance.initialize(shares);\n    }\n  }\n\n  /**\n   * @notice Returns the address for the proxy contract which would represent the given split terms.\n   * @dev The contract may or may not already be deployed at the address returned.\n   * Ensure that it is deployed before sending funds to this address.\n   */\n  function getPredictedSplitAddress(Share[] memory shares) external view returns (address) {\n    bytes32 salt = keccak256(abi.encode(shares));\n    return Clones.predictDeterministicAddress(address(this), salt);\n  }\n\n  /**\n   * @notice Called once to configure the contract after the initial deployment.\n   * @dev This will be called by `createSplit` after deploying the proxy so it should never be called directly.\n   */\n  function initialize(Share[] memory shares) external initializer {\n    require(shares.length >= 2, \"Split: Too few recipients\");\n    require(shares.length <= 5, \"Split: Too many recipients\");\n    uint256 total;\n    unchecked {\n      // The array length cannot overflow 256 bits.\n      for (uint256 i = 0; i < shares.length; ++i) {\n        require(shares[i].percentInBasisPoints < BASIS_POINTS, \"Split: Share must be less than 100%\");\n        // Require above ensures total will not overlow.\n        total += shares[i].percentInBasisPoints;\n        _shares.push(\n          ShareCompressed({\n            recipient: shares[i].recipient,\n            percentInBasisPoints: uint16(shares[i].percentInBasisPoints)\n          })\n        );\n        emit PercentSplitShare(shares[i].recipient, shares[i].percentInBasisPoints);\n      }\n    }\n    require(total == BASIS_POINTS, \"Split: Total amount must equal 100%\");\n  }\n\n  /**\n   * @notice Returns a tuple with the terms of this split.\n   */\n  function getShares() external view returns (Share[] memory shares) {\n    shares = new Share[](_shares.length);\n    for (uint256 i = 0; i < shares.length; ++i) {\n      shares[i] = Share({ recipient: _shares[i].recipient, percentInBasisPoints: _shares[i].percentInBasisPoints });\n    }\n  }\n\n  /**\n   * @notice Returns how many recipients are part of this split.\n   */\n  function getShareLength() external view returns (uint256) {\n    return _shares.length;\n  }\n\n  /**\n   * @notice Returns a recipient in this split.\n   */\n  function getShareRecipientByIndex(uint256 index) external view returns (address payable) {\n    return _shares[index].recipient;\n  }\n\n  /**\n   * @notice Returns a recipient's percent share in basis points.\n   */\n  function getPercentInBasisPointsByIndex(uint256 index) external view returns (uint256) {\n    return _shares[index].percentInBasisPoints;\n  }\n\n  /**\n   * @notice Forwards any ETH received to the recipients in this split.\n   * @dev Each recipient increases the gas required to split\n   * and contract recipients may significantly increase the gas required.\n   */\n  receive() external payable {\n    _splitETH(msg.value);\n  }\n\n  /**\n   * @notice Allows any ETH stored by the contract to be split among recipients.\n   * @dev Normally ETH is forwarded as it comes in, but a balance in this contract\n   * is possible if it was sent before the contract was created or if self destruct was used.\n   */\n  function splitETH() external {\n    _splitETH(address(this).balance);\n  }\n\n  function _splitETH(uint256 value) private {\n    if (value != 0) {\n      uint256 totalSent;\n      uint256 amountToSend;\n      unchecked {\n        for (uint256 i = _shares.length - 1; i != 0; i--) {\n          ShareCompressed memory share = _shares[i];\n          amountToSend = (value * share.percentInBasisPoints) / BASIS_POINTS;\n          totalSent += amountToSend;\n          share.recipient.sendValue(amountToSend);\n          emit ETHTransferred(share.recipient, amountToSend);\n        }\n        // Favor the 1st recipient if there are any rounding issues\n        amountToSend = value - totalSent;\n      }\n      _shares[0].recipient.sendValue(amountToSend);\n      emit ETHTransferred(_shares[0].recipient, amountToSend);\n    }\n  }\n\n  /**\n   * @notice Anyone can call this function to split all available tokens at the provided address between the recipients.\n   * @dev This contract is built to split ETH payments. The ability to attempt to split ERC20 tokens is here\n   * just in case tokens were also sent so that they don't get locked forever in the contract.\n   */\n  function splitERC20Tokens(IERC20 erc20Contract) external {\n    require(_splitERC20Tokens(erc20Contract), \"Split: ERC20 split failed\");\n  }\n\n  function _splitERC20Tokens(IERC20 erc20Contract) private returns (bool) {\n    try erc20Contract.balanceOf(address(this)) returns (uint256 balance) {\n      if (balance == 0) {\n        return false;\n      }\n      uint256 amountToSend;\n      uint256 totalSent;\n      unchecked {\n        for (uint256 i = _shares.length - 1; i != 0; i--) {\n          ShareCompressed memory share = _shares[i];\n          bool success;\n          (success, amountToSend) = balance.tryMul(share.percentInBasisPoints);\n          if (!success) {\n            return false;\n          }\n          amountToSend /= BASIS_POINTS;\n          totalSent += amountToSend;\n          try erc20Contract.transfer(share.recipient, amountToSend) {\n            emit ERC20Transferred(address(erc20Contract), share.recipient, amountToSend);\n          } catch {\n            return false;\n          }\n        }\n        // Favor the 1st recipient if there are any rounding issues\n        amountToSend = balance - totalSent;\n      }\n      try erc20Contract.transfer(_shares[0].recipient, amountToSend) {\n        emit ERC20Transferred(address(erc20Contract), _shares[0].recipient, amountToSend);\n      } catch {\n        return false;\n      }\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  /**\n   * @notice Allows the split recipients to make an arbitrary contract call.\n   * @dev This is provided to allow recovering from unexpected scenarios,\n   * such as receiving an NFT at this address.\n   *\n   * It will first attempt a fair split of ERC20 tokens before proceeding.\n   *\n   * This contract is built to split ETH payments. The ability to attempt to make other calls is here\n   * just in case other assets were also sent so that they don't get locked forever in the contract.\n   */\n  function proxyCall(address payable target, bytes memory callData) external onlyRecipient {\n    require(\n      !callData.startsWith(type(IERC20Approve).interfaceId) &&\n        !callData.startsWith(type(IERC20IncreaseAllowance).interfaceId),\n      \"Split: ERC20 tokens must be split\"\n    );\n    _splitERC20Tokens(IERC20(target));\n    target.functionCall(callData);\n  }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (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 proxied contracts do not make use of 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"
      },
      "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.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 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     * [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 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"
      },
      "@openzeppelin/contracts/utils/math/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/Clones.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create opcode, which should never revert.\n     */\n    function clone(address implementation) internal returns (address instance) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n            instance := create(0, ptr, 0x37)\n        }\n        require(instance != address(0), \"ERC1167: create failed\");\n    }\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create2 opcode and a `salt` to deterministically deploy\n     * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n     * the clones cannot be deployed twice at the same address.\n     */\n    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n            instance := create2(0, ptr, 0x37, salt)\n        }\n        require(instance != address(0), \"ERC1167: create2 failed\");\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)\n            mstore(add(ptr, 0x38), shl(0x60, deployer))\n            mstore(add(ptr, 0x4c), salt)\n            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))\n            predicted := keccak256(add(ptr, 0x37), 0x55)\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(address implementation, bytes32 salt)\n        internal\n        view\n        returns (address predicted)\n    {\n        return predictDeterministicAddress(implementation, salt, address(this));\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"
      },
      "contracts/interfaces/IERC20Approve.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\ninterface IERC20Approve {\n  function approve(address spender, uint256 amount) external returns (bool);\n}\n"
      },
      "contracts/interfaces/IERC20IncreaseAllowance.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\ninterface IERC20IncreaseAllowance {\n  function increaseAllowance(address spender, uint256 addedValue) external returns (bool);\n}\n"
      },
      "contracts/libraries/BytesLibrary.sol": {
        "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\n\npragma solidity ^0.8.0;\n\nerror BytesLibrary_Expected_Address_Not_Found();\n\n/**\n * @title A library for manipulation of byte arrays.\n */\nlibrary BytesLibrary {\n  /**\n   * @dev Replace the address at the given location in a byte array if the contents at that location\n   * match the expected address.\n   */\n  function replaceAtIf(\n    bytes memory data,\n    uint256 startLocation,\n    address expectedAddress,\n    address newAddress\n  ) internal pure {\n    bytes memory expectedData = abi.encodePacked(expectedAddress);\n    bytes memory newData = abi.encodePacked(newAddress);\n    unchecked {\n      // An address is 20 bytes long\n      for (uint256 i = 0; i < 20; ++i) {\n        uint256 dataLocation = startLocation + i;\n        if (data[dataLocation] != expectedData[i]) {\n          revert BytesLibrary_Expected_Address_Not_Found();\n        }\n        data[dataLocation] = newData[i];\n      }\n    }\n  }\n\n  /**\n   * @dev Checks if the call data starts with the given function signature.\n   */\n  function startsWith(bytes memory callData, bytes4 functionSig) internal pure returns (bool) {\n    // A signature is 4 bytes long\n    if (callData.length < 4) {\n      return false;\n    }\n    unchecked {\n      for (uint256 i = 0; i < 4; ++i) {\n        if (callData[i] != functionSig[i]) {\n          return false;\n        }\n      }\n    }\n\n    return true;\n  }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 1337
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}