{
  "address": "0x0d97643EE1051B523E4e3b66Df3640bBA6C0F79f",
  "abi": [
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "newController",
          "type": "address"
        }
      ],
      "name": "ControllerRegister",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "address",
          "name": "newController",
          "type": "address"
        }
      ],
      "name": "ControllerRemove",
      "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": "",
          "type": "address"
        }
      ],
      "name": "controllerRegistry",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_controller",
          "type": "address"
        }
      ],
      "name": "isRegistered",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_controller",
          "type": "address"
        }
      ],
      "name": "registerController",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "_controller",
          "type": "address"
        }
      ],
      "name": "removeController",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    }
  ],
  "transactionHash": "0x3cdfe619667656e1d85ef2f10b30caf45b3f51367c31241219e6a539304846ac",
  "receipt": {
    "to": null,
    "from": "0x2149A222feD42fefc3A120B3DdA34482190fC666",
    "contractAddress": "0x0d97643EE1051B523E4e3b66Df3640bBA6C0F79f",
    "transactionIndex": 42,
    "gasUsed": "381475",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400800000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000010000000000000000000000100000000000000000000000000010000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x8f94bbccb9416e7d984a3450b9f943b99849fc30e594902676f5158d38419d81",
    "transactionHash": "0x3cdfe619667656e1d85ef2f10b30caf45b3f51367c31241219e6a539304846ac",
    "logs": [
      {
        "transactionIndex": 42,
        "blockNumber": 13640382,
        "transactionHash": "0x3cdfe619667656e1d85ef2f10b30caf45b3f51367c31241219e6a539304846ac",
        "address": "0x0d97643EE1051B523E4e3b66Df3640bBA6C0F79f",
        "topics": [
          "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x0000000000000000000000002149a222fed42fefc3a120b3dda34482190fc666"
        ],
        "data": "0x",
        "logIndex": 60,
        "blockHash": "0x8f94bbccb9416e7d984a3450b9f943b99849fc30e594902676f5158d38419d81"
      }
    ],
    "blockNumber": 13640382,
    "cumulativeGasUsed": "2500094",
    "status": 1,
    "byzantium": true
  },
  "args": [],
  "solcInputHash": "ad4e5f37a674081d15ff85090ee8a137",
  "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newController\",\"type\":\"address\"}],\"name\":\"ControllerRegister\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newController\",\"type\":\"address\"}],\"name\":\"ControllerRemove\",\"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\":\"\",\"type\":\"address\"}],\"name\":\"controllerRegistry\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"name\":\"isRegistered\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"name\":\"registerController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_controller\",\"type\":\"address\"}],\"name\":\"removeController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"isRegistered(address)\":{\"params\":{\"_controller\":\"The address to check if registered as a controller\"},\"returns\":{\"_0\":\"Boolean representing if the address is a registered as a controller\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"registerController(address)\":{\"params\":{\"_controller\":\"The address to register as a controller\"}},\"removeController(address)\":{\"params\":{\"_controller\":\"The address to remove as a controller\"}},\"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.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ControllerRegistry.sol\":\"ControllerRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"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/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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"contracts/ControllerRegistry.sol\":{\"content\":\"pragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./interfaces/IControllerRegistry.sol\\\";\\n\\ncontract ControllerRegistry is IControllerRegistry, Ownable {\\n    mapping(address => bool) public controllerRegistry;\\n\\n    event ControllerRegister(address newController);\\n    event ControllerRemove(address newController);\\n\\n    /**\\n     * @param _controller The address to register as a controller\\n     */\\n    function registerController(address _controller) external onlyOwner {\\n        require(_controller != address(0), \\\"Invalid address\\\");\\n        emit ControllerRegister(_controller);\\n        controllerRegistry[_controller] = true;\\n    }\\n\\n    /**\\n     * @param _controller The address to remove as a controller\\n     */\\n    function removeController(address _controller) external onlyOwner {\\n        require(_controller != address(0), \\\"Invalid address\\\");\\n        emit ControllerRemove(_controller);\\n        controllerRegistry[_controller] = false;\\n    }\\n\\n    /**\\n     * @param _controller The address to check if registered as a controller\\n     * @return Boolean representing if the address is a registered as a controller\\n     */\\n    function isRegistered(address _controller)\\n        external\\n        view\\n        override\\n        returns (bool)\\n    {\\n        return controllerRegistry[_controller];\\n    }\\n}\\n\",\"keccak256\":\"0xff189b7adb14bf098bb9d4b76af0cf4794599350a4d2468f83363579b16f4200\"},\"contracts/interfaces/IControllerRegistry.sol\":{\"content\":\"pragma solidity 0.8.7;\\n\\n\\ninterface IControllerRegistry{\\n\\n    /**\\n     * @param _controller Address to check if registered as a controller\\n     * @return Boolean representing if the address is a registered as a controller\\n     */\\n    function isRegistered(address _controller) external view returns (bool);\\n\\n}\\n\",\"keccak256\":\"0x02e7853f4677cafd67f4a486cea842929067ca7b764b468e54922180998d5c4c\"}},\"version\":1}",
  "bytecode": "0x608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61057f8061007e6000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063c3c5a5471161005b578063c3c5a547146100df578063d91ae8c21461010b578063f2fde38b1461011e578063f6a74ed71461013157600080fd5b806301df60a414610082578063715018a6146100ba5780638da5cb5b146100c4575b600080fd5b6100a5610090366004610519565b60016020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100c2610144565b005b6000546040516001600160a01b0390911681526020016100b1565b6100a56100ed366004610519565b6001600160a01b031660009081526001602052604090205460ff1690565b6100c2610119366004610519565b6101af565b6100c261012c366004610519565b6102c2565b6100c261013f366004610519565b6103a4565b6000546001600160a01b031633146101a35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6101ad60006104b1565b565b6000546001600160a01b031633146102095760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161019a565b6001600160a01b03811661025f5760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015260640161019a565b6040516001600160a01b03821681527f9713ba9c15f2a00e5eec60574362fa39c45d80fc1e6a0d97b6b7593eed4b25ed9060200160405180910390a16001600160a01b03166000908152600160208190526040909120805460ff19169091179055565b6000546001600160a01b0316331461031c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161019a565b6001600160a01b0381166103985760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161019a565b6103a1816104b1565b50565b6000546001600160a01b031633146103fe5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161019a565b6001600160a01b0381166104545760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015260640161019a565b6040516001600160a01b03821681527f6570671ae1af213b3b25d236e7cd633f016b2433e178e4e9b36a29906d6f7fb39060200160405180910390a16001600160a01b03166000908152600160205260409020805460ff19169055565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561052b57600080fd5b81356001600160a01b038116811461054257600080fd5b939250505056fea2646970667358221220e547ff06193ed0af3669a0a4d936021b2643cf4df7dc982d0c742192e1ba402664736f6c63430008070033",
  "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063c3c5a5471161005b578063c3c5a547146100df578063d91ae8c21461010b578063f2fde38b1461011e578063f6a74ed71461013157600080fd5b806301df60a414610082578063715018a6146100ba5780638da5cb5b146100c4575b600080fd5b6100a5610090366004610519565b60016020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100c2610144565b005b6000546040516001600160a01b0390911681526020016100b1565b6100a56100ed366004610519565b6001600160a01b031660009081526001602052604090205460ff1690565b6100c2610119366004610519565b6101af565b6100c261012c366004610519565b6102c2565b6100c261013f366004610519565b6103a4565b6000546001600160a01b031633146101a35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6101ad60006104b1565b565b6000546001600160a01b031633146102095760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161019a565b6001600160a01b03811661025f5760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015260640161019a565b6040516001600160a01b03821681527f9713ba9c15f2a00e5eec60574362fa39c45d80fc1e6a0d97b6b7593eed4b25ed9060200160405180910390a16001600160a01b03166000908152600160208190526040909120805460ff19169091179055565b6000546001600160a01b0316331461031c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161019a565b6001600160a01b0381166103985760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161019a565b6103a1816104b1565b50565b6000546001600160a01b031633146103fe5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161019a565b6001600160a01b0381166104545760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015260640161019a565b6040516001600160a01b03821681527f6570671ae1af213b3b25d236e7cd633f016b2433e178e4e9b36a29906d6f7fb39060200160405180910390a16001600160a01b03166000908152600160205260409020805460ff19169055565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561052b57600080fd5b81356001600160a01b038116811461054257600080fd5b939250505056fea2646970667358221220e547ff06193ed0af3669a0a4d936021b2643cf4df7dc982d0c742192e1ba402664736f6c63430008070033",
  "devdoc": {
    "kind": "dev",
    "methods": {
      "isRegistered(address)": {
        "params": {
          "_controller": "The address to check if registered as a controller"
        },
        "returns": {
          "_0": "Boolean representing if the address is a registered as a controller"
        }
      },
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "registerController(address)": {
        "params": {
          "_controller": "The address to register as a controller"
        }
      },
      "removeController(address)": {
        "params": {
          "_controller": "The address to remove as a controller"
        }
      },
      "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."
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      }
    },
    "version": 1
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 775,
        "contract": "contracts/ControllerRegistry.sol:ControllerRegistry",
        "label": "_owner",
        "offset": 0,
        "slot": "0",
        "type": "t_address"
      },
      {
        "astId": 4302,
        "contract": "contracts/ControllerRegistry.sol:ControllerRegistry",
        "label": "controllerRegistry",
        "offset": 0,
        "slot": "1",
        "type": "t_mapping(t_address,t_bool)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_mapping(t_address,t_bool)": {
        "encoding": "mapping",
        "key": "t_address",
        "label": "mapping(address => bool)",
        "numberOfBytes": "32",
        "value": "t_bool"
      }
    }
  }
}