creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/actions/common/CollectFee.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { Executable } from \"../common/Executable.sol\";\nimport { UseStorageSlot, StorageSlot, Write, Read } from \"../../libs/UseStorageSlot.sol\";\nimport { UseRegistry } from \"../../libs/UseRegistry.sol\";\nimport { ServiceRegistry } from \"../../core/ServiceRegistry.sol\";\nimport { SafeERC20, IERC20 } from \"../../libs/SafeERC20.sol\";\n\n/**\n * @title CollectFee | Fee Collection Action Contract\n * @notice Collects a fee based on a transaction amount read from an OperationStorage slot\n */\ncontract CollectFee is Executable, UseStorageSlot, UseRegistry {\n    using SafeERC20 for IERC20;\n    using Write for StorageSlot.TransactionStorage;\n    using Read for StorageSlot.TransactionStorage;\n\n    // Fee percentage (e.g., 1% = 100, 0.5% = 50)\n    uint256 public immutable feePercentage;\n    address public immutable feeRecipient;\n    uint256 constant DIVISOR = 10000;\n\n    constructor(address _registry, uint256 _feePercentage, address _feeRecipient) UseRegistry(ServiceRegistry(_registry)) {\n        feePercentage = _feePercentage;\n        feeRecipient = _feeRecipient;\n    }\n\n    event FeePaid(address indexed beneficiary, uint256 amount, address token);\n\n    /**\n     * @param data Encoded calldata that conforms to the asset address and optionally other parameters\n     */\n    function execute(bytes calldata data, uint8[] memory paramsMap) external payable override {\n        address asset = parseInputs(data);\n        uint256 transactionAmount = store().readUint(bytes32(0), paramsMap[0]);\n        uint256 feeAmount = (transactionAmount * feePercentage) / DIVISOR;\n\n        // Transfer fee from the user's proxy to the feeRecipient\n        IERC20(asset).safeTransfer(feeRecipient, feeAmount);\n\n        emit FeePaid(feeRecipient, feeAmount, asset);\n    }\n\n    function parseInputs(bytes memory _callData) public pure returns (address asset) {\n        return abi.decode(_callData, (address));\n    }\n}\n"
      },
      "contracts/actions/common/Executable.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\n/**\n * @title Shared Action Executable interface\n * @notice Provides a dma-common interface for an execute method to all Action\n */\ninterface Executable {\n  function execute(bytes calldata data, uint8[] memory paramsMap) external payable;\n}\n"
      },
      "contracts/core/constants/Common.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nstring constant OPERATION_STORAGE = \"OperationStorage_5\";\nstring constant OPERATION_EXECUTOR = \"OperationExecutor_5\";\nstring constant OPERATIONS_REGISTRY = \"OperationsRegistry_5\";\nstring constant CHAINLOG_VIEWER = \"ChainLogView\";\nstring constant ONE_INCH_AGGREGATOR = \"OneInchAggregator\";\nstring constant ONE_INCH_AGGREGATOR5 = \"OneInchAggregator5\";\nstring constant DS_GUARD_FACTORY = \"DSGuardFactory\";\nstring constant WETH = \"WETH\";\nstring constant DAI = \"DAI\";\nuint256 constant RAY = 10 ** 27;\nbytes32 constant NULL = \"\";\n\n/**\n * @dev We do not include patch versions in contract names to allow\n * for hotfixes of Action dma-contracts\n * and to limit updates to TheGraph\n * if the types encoded in emitted events change then use a minor version and\n * update the ServiceRegistry with a new entry\n * and update TheGraph decoding accordingly\n */\nstring constant POSITION_CREATED_ACTION = \"PositionCreated\";\n\nstring constant UNISWAP_ROUTER = \"UniswapRouter\";\nstring constant SWAP = \"Swap_2\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n"
      },
      "contracts/core/OperationStorage.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { ServiceRegistry } from \"./ServiceRegistry.sol\";\n\n/**\n * @title Operation Storage\n * @notice Stores the return values from Actions during an Operation's execution\n * @dev valuesHolders is an array of t/x initiators (msg.sender) who have pushed values to Operation Storage\n * returnValues is a mapping between a msg.sender and an array of Action return values generated by that senders transaction\n */\ncontract OperationStorage {\n  uint8 internal action = 0;\n  bytes32[] public actions;\n  bool[] public optionals;\n  mapping(address => bytes32[]) public returnValues;\n  address[] public valuesHolders;\n  bool private locked;\n  address private whoLocked;\n  address public initiator;\n  address immutable operationExecutorAddress;\n\n  ServiceRegistry internal immutable registry;\n\n  constructor(ServiceRegistry _registry, address _operationExecutorAddress) {\n    registry = _registry;\n    operationExecutorAddress = _operationExecutorAddress;\n  }\n\n  /**\n   * @dev Locks storage to protect against re-entrancy attacks.@author\n   */\n  function lock() external {\n    locked = true;\n    whoLocked = msg.sender;\n  }\n\n  /**\n   * @dev Only the original locker can unlock the contract at the end of the transaction\n   */\n  function unlock() external {\n    require(whoLocked == msg.sender, \"Only the locker can unlock\");\n    require(locked, \"Not locked\");\n    locked = false;\n    whoLocked = address(0);\n  }\n\n  /**\n   * @dev Sets the initiator of the original call\n   * Is used by Automation Bot branch in the onFlashloan callback in Operation Executor\n   * Ensures that third party calls to Operation Storage do not maliciously override values in Operation Storage\n   * @param _initiator Sets the initiator to Operation Executor contract when storing return values from flashloan nested Action\n   */\n  function setInitiator(address _initiator) external {\n    require(msg.sender == operationExecutorAddress);\n    initiator = _initiator;\n  }\n\n  /**\n   * @param _actions Stores the Actions currently being executed for a given Operation and their optionality\n   */\n  function setOperationActions(bytes32[] memory _actions, bool[] memory _optionals) external {\n    actions = _actions;\n    optionals = _optionals;\n  }\n\n  /**\n   * @param actionHash Checks the current action has against the expected action hash\n   */\n  function verifyAction(bytes32 actionHash, bool skipped) external {\n    if (skipped) {\n      require(optionals[action], \"Action cannot be skipped\");\n    }\n    require(actions[action] == actionHash, \"incorrect-action\");\n    registry.getServiceAddress(actionHash);\n    action++;\n  }\n\n  /**\n   * @dev Custom operations have no Actions stored in Operation Registry\n   * @return Returns true / false depending on whether the Operation has any actions to verify the Operation against\n   */\n  function hasActionsToVerify() external view returns (bool) {\n    return actions.length > 0;\n  }\n\n  /**\n   * @param value Pushes a bytes32 to end of the returnValues array\n   */\n  function push(bytes32 value) external {\n    address who = msg.sender;\n    if (who == operationExecutorAddress) {\n      who = initiator;\n    }\n\n    if (returnValues[who].length == 0) {\n      valuesHolders.push(who);\n    }\n    returnValues[who].push(value);\n  }\n\n  /**\n   * @dev Values are stored against an address (who)\n   * This ensures that malicious actors looking to push values to Operation Storage mid transaction cannot overwrite values\n   * @param index The index of the desired value\n   * @param who The msg.sender address responsible for storing values\n   */\n  function at(uint256 index, address who) external view returns (bytes32) {\n    if (who == operationExecutorAddress) {\n      who = initiator;\n    }\n    return returnValues[who][index];\n  }\n\n  /**\n   * @param who The msg.sender address responsible for storing values\n   * @return The length of return values stored against a given msg.sender address\n   */\n  function len(address who) external view returns (uint256) {\n    if (who == operationExecutorAddress) {\n      who = initiator;\n    }\n    return returnValues[who].length;\n  }\n\n  /**\n   * @dev Clears storage in preparation for the next Operation\n   */\n  function clearStorage() external {\n    delete action;\n    delete actions;\n    for (uint256 i = 0; i < valuesHolders.length; i++) {\n      delete returnValues[valuesHolders[i]];\n    }\n    delete valuesHolders;\n  }\n}\n"
      },
      "contracts/core/ServiceRegistry.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\n/// ServiceRegistry.sol\n\n// Copyright (C) 2021-2021 Oazo Apps Limited\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\npragma solidity ^0.8.0;\n\ncontract ServiceRegistry {\n  uint256 public constant MAX_DELAY = 30 days;\n\n  mapping(bytes32 => uint256) public lastExecuted;\n  mapping(bytes32 => address) private namedService;\n  mapping(bytes32 => bool) private invalidHashes;\n  address public owner;\n  uint256 public requiredDelay;\n\n  modifier validateInput(uint256 len) {\n    require(msg.data.length == len, \"registry/illegal-padding\");\n    _;\n  }\n\n  modifier delayedExecution() {\n    bytes32 operationHash = keccak256(msg.data);\n    uint256 reqDelay = requiredDelay;\n\n    /* solhint-disable not-rely-on-time */\n    if (lastExecuted[operationHash] == 0 && reqDelay > 0) {\n      // not called before, scheduled for execution\n      lastExecuted[operationHash] = block.timestamp;\n      emit ChangeScheduled(operationHash, block.timestamp + reqDelay, msg.data);\n    } else {\n      require(block.timestamp - reqDelay > lastExecuted[operationHash], \"registry/delay-too-small\");\n      emit ChangeApplied(operationHash, block.timestamp, msg.data);\n      _;\n      lastExecuted[operationHash] = 0;\n    }\n    /* solhint-enable not-rely-on-time */\n  }\n\n  modifier onlyOwner() {\n    require(msg.sender == owner, \"registry/only-owner\");\n    _;\n  }\n\n  constructor(uint256 initialDelay) {\n    require(initialDelay <= MAX_DELAY, \"registry/invalid-delay\");\n    requiredDelay = initialDelay;\n    owner = msg.sender;\n  }\n\n  function transferOwnership(\n    address newOwner\n  ) external onlyOwner validateInput(36) delayedExecution {\n    owner = newOwner;\n  }\n\n  function changeRequiredDelay(\n    uint256 newDelay\n  ) external onlyOwner validateInput(36) delayedExecution {\n    require(newDelay <= MAX_DELAY, \"registry/invalid-delay\");\n    requiredDelay = newDelay;\n  }\n\n  function getServiceNameHash(string memory name) external pure returns (bytes32) {\n    return keccak256(abi.encodePacked(name));\n  }\n\n  function addNamedService(\n    bytes32 serviceNameHash,\n    address serviceAddress\n  ) external onlyOwner validateInput(68) delayedExecution {\n    require(invalidHashes[serviceNameHash] == false, \"registry/service-name-used-before\");\n    require(namedService[serviceNameHash] == address(0), \"registry/service-override\");\n    namedService[serviceNameHash] = serviceAddress;\n    emit NamedServiceAdded(serviceNameHash, serviceAddress);\n  }\n\n  function removeNamedService(bytes32 serviceNameHash) external onlyOwner validateInput(36) {\n    require(namedService[serviceNameHash] != address(0), \"registry/service-does-not-exist\");\n    namedService[serviceNameHash] = address(0);\n    invalidHashes[serviceNameHash] = true;\n    emit NamedServiceRemoved(serviceNameHash);\n  }\n\n  function getRegisteredService(string memory serviceName) external view returns (address) {\n    return namedService[keccak256(abi.encodePacked(serviceName))];\n  }\n\n  function getServiceAddress(bytes32 serviceNameHash) external view returns (address) {\n    return namedService[serviceNameHash];\n  }\n\n  function clearScheduledExecution(\n    bytes32 scheduledExecution\n  ) external onlyOwner validateInput(36) {\n    require(lastExecuted[scheduledExecution] > 0, \"registry/execution-not-scheduled\");\n    lastExecuted[scheduledExecution] = 0;\n    emit ChangeCancelled(scheduledExecution);\n  }\n\n  event ChangeScheduled(bytes32 dataHash, uint256 scheduledFor, bytes data);\n  event ChangeApplied(bytes32 dataHash, uint256 appliedAt, bytes data);\n  event ChangeCancelled(bytes32 dataHash);\n  event NamedServiceRemoved(bytes32 nameHash);\n  event NamedServiceAdded(bytes32 nameHash, address service);\n}\n"
      },
      "contracts/interfaces/tokens/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.15;\n\ninterface IERC20 {\n  function totalSupply() external view returns (uint256 supply);\n\n  function balanceOf(address _owner) external view returns (uint256 balance);\n\n  function transfer(address _to, uint256 _value) external returns (bool success);\n\n  function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);\n\n  function approve(address _spender, uint256 _value) external returns (bool success);\n\n  function allowance(address _owner, address _spender) external view returns (uint256 remaining);\n\n  function decimals() external view returns (uint256 digits);\n}\n"
      },
      "contracts/libs/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.1;\n\nlibrary Address {\n  function isContract(address account) internal view returns (bool) {\n    // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n    // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n    // for accounts without code, i.e. `keccak256('')`\n    bytes32 codehash;\n    bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n    // solhint-disable-next-line no-inline-assembly\n    assembly {\n      codehash := extcodehash(account)\n    }\n    return (codehash != accountHash && codehash != 0x0);\n  }\n\n  function sendValue(address payable recipient, uint256 amount) internal {\n    require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n    // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n    (bool success, ) = recipient.call{ value: amount }(\"\");\n    require(success, \"Address: unable to send value, recipient may have reverted\");\n  }\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  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  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  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    return _functionCallWithValue(target, data, value, errorMessage);\n  }\n\n  function _functionCallWithValue(\n    address target,\n    bytes memory data,\n    uint256 weiValue,\n    string memory errorMessage\n  ) private returns (bytes memory) {\n    require(isContract(target), \"Address: call to non-contract\");\n\n    (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);\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        // solhint-disable-next-line no-inline-assembly\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  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    if (success) {\n      return returndata;\n    }\n\n    if (returndata.length > 0) {\n      assembly {\n        let returndata_size := mload(returndata)\n        revert(add(32, returndata), returndata_size)\n      }\n    }\n\n    revert(errorMessage);\n  }\n}\n"
      },
      "contracts/libs/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.8.1;\n\nimport { IERC20 } from \"../interfaces/tokens/IERC20.sol\";\nimport { Address } from \"./Address.sol\";\nimport { SafeMath } from \"./SafeMath.sol\";\n\nlibrary SafeERC20 {\n  using SafeMath for uint256;\n  using Address for address;\n\n  function safeTransfer(IERC20 token, address to, uint256 value) internal {\n    _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n  }\n\n  function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(token.transferFrom.selector, from, to, value)\n    );\n  }\n\n  /**\n   * @dev Deprecated. This function has issues similar to the ones found in\n   * {ERC20-approve}, and its usage is discouraged.\n   */\n  function safeApprove(IERC20 token, address spender, uint256 value) internal {\n    _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n    _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n  }\n\n  function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n    uint256 newAllowance = token.allowance(address(this), spender).add(value);\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(token.approve.selector, spender, newAllowance)\n    );\n  }\n\n  function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n    uint256 newAllowance = token.allowance(address(this), spender).sub(\n      value,\n      \"SafeERC20: decreased allowance below zero\"\n    );\n    _callOptionalReturn(\n      token,\n      abi.encodeWithSelector(token.approve.selector, spender, newAllowance)\n    );\n  }\n\n  function _callOptionalReturn(IERC20 token, bytes memory data) private {\n    bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n    if (returndata.length > 0) {\n      // Return data is optional\n      // solhint-disable-next-line max-line-length\n      require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n  }\n}\n"
      },
      "contracts/libs/SafeMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.15;\n\nlibrary SafeMath {\n  function add(uint256 a, uint256 b) internal pure returns (uint256) {\n    uint256 c = a + b;\n    require(c >= a, \"SafeMath: addition overflow\");\n\n    return c;\n  }\n\n  function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n    return sub(a, b, \"SafeMath: subtraction overflow\");\n  }\n\n  function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n    require(b <= a, errorMessage);\n    uint256 c = a - b;\n\n    return c;\n  }\n\n  function mul(uint256 a, uint256 b) internal pure returns (uint256) {\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) {\n      return 0;\n    }\n\n    uint256 c = a * b;\n    require(c / a == b, \"SafeMath: multiplication overflow\");\n\n    return c;\n  }\n\n  function div(uint256 a, uint256 b) internal pure returns (uint256) {\n    return div(a, b, \"SafeMath: division by zero\");\n  }\n\n  function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n    require(b > 0, errorMessage);\n    uint256 c = a / b;\n    // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n    return c;\n  }\n\n  function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n    return mod(a, b, \"SafeMath: modulo by zero\");\n  }\n\n  function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n    require(b != 0, errorMessage);\n    return a % b;\n  }\n}\n"
      },
      "contracts/libs/UseRegistry.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { OperationStorage } from \"../core/OperationStorage.sol\";\nimport { ServiceRegistry } from \"../core/ServiceRegistry.sol\";\nimport { OPERATION_STORAGE } from \"../core/constants/Common.sol\";\n\n/**\n * @title UseRegistry contract\n * @notice Provides common interface for all Actions to access the ServiceRegistry contract\n */\n\ncontract UseRegistry { \n  ServiceRegistry private immutable _registry;\n  constructor(ServiceRegistry registry_) {\n    _registry = registry_;\n  } \n\n  function getRegisteredService(string memory service) internal view returns (address) {\n    return _registry.getRegisteredService(service); \n  }\n}\n"
      },
      "contracts/libs/UseStorageSlot.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\n/**\n * @title A library that operates on a storage slot\n * @notice It is used to storage all kind of information that is going to be used during a transaction life time.\n * @dev The system of contracts that utilize this library work under the assumption\n * that all contracts are called in the scope of a proxy. Using the library will create a storage pointer\n * to a slot in the Proxy instance.\n * The `TransactionStorage` structure contains the following properties:\n *  - actions - Each executed action's hash is pushed into the array. At the end of the operation execution,\n * this values are concatenated ( abi.encodePacked ) .\n *  - returnedValues - Used to store values from actions. It is used to share values between actions and\n * other interested contacts\n */\nlibrary StorageSlot {\n  struct TransactionStorage {\n    bytes32[] actions;\n    bytes32[] returnedValues;\n  }\n\n  /**\n   * @notice Used to get a storage slot at a specific slot position\n   */\n  function getTransactionStorage() internal pure returns (TransactionStorage storage tStorage) {\n    bytes32 slotPosition = bytes32(uint256(keccak256(\"proxy.transaction.storage\")) - 1);\n\n    assembly {\n      tStorage.slot := slotPosition\n    }\n  }\n}\n\n/**\n * @title Used to read from the StorageSlot\n * @notice There is a structure used in the StorageSlot library that is used\n * to create a storage pointer. This library read from a specific property of that structure.\n * It is used to read a specific returned value from an Action.\n */\nlibrary Read {\n  function read(\n    StorageSlot.TransactionStorage storage _storage,\n    bytes32 param,\n    uint256 paramMapping\n  ) internal view returns (bytes32) {\n    if (paramMapping > 0) {\n      return _storage.returnedValues[paramMapping - 1];\n    }\n\n    return param;\n  }\n\n  function readUint(\n    StorageSlot.TransactionStorage storage _storage,\n    bytes32 param,\n    uint256 paramMapping\n  ) internal view returns (uint256) {\n    return uint256(read(_storage, param, paramMapping));\n  }\n}\n\n/**\n * @title Used to write to the StorageSlot\n * @notice There is a structure used in the StorageSlot library that is used\n * to create a storage pointer. This library writes to a specific property of that structure\n * that is responsible for sharing the returned values from an Action.\n */\nlibrary Write {\n  function write(StorageSlot.TransactionStorage storage _storage, bytes32 value) internal {\n    _storage.returnedValues.push(value);\n  }\n}\n\nabstract contract UseStorageSlot {\n  function store() internal pure returns (StorageSlot.TransactionStorage storage) {\n    return StorageSlot.getTransactionStorage();\n  }\n}"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 0
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}