{
  "language": "Solidity",
  "sources": {
    "contracts/ControllerRegistry.sol": {
      "content": "pragma solidity ^0.8.7;\n\nimport \"lib/openzeppelin-contracts/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"
    },
    "lib/openzeppelin-contracts/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 Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\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 the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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"
    },
    "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"
    },
    "lib/openzeppelin-contracts/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/MemberToken.sol": {
      "content": "pragma solidity ^0.8.7;\n\n/* solhint-disable indent */\n\nimport \"lib/openzeppelin-contracts/contracts/access/Ownable.sol\";\nimport \"lib/openzeppelin-contracts/contracts/utils/Address.sol\";\nimport \"lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol\";\nimport \"lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol\";\nimport \"./interfaces/IControllerRegistry.sol\";\nimport \"./interfaces/IControllerBase.sol\";\n\ncontract MemberToken is ERC1155Supply, Ownable {\n    using Address for address;\n\n    IControllerRegistry public controllerRegistry;\n\n    mapping(uint256 => address) public memberController;\n\n    uint256 public nextAvailablePodId = 0;\n    string public _contractURI =\n        \"https://orcaprotocol-nft.vercel.app/assets/contract-metadata\";\n\n    event MigrateMemberController(uint256 podId, address newController);\n\n    /**\n     * @param _controllerRegistry The address of the ControllerRegistry contract\n     */\n    constructor(address _controllerRegistry, string memory uri) ERC1155(uri) {\n        require(_controllerRegistry != address(0), \"Invalid address\");\n        controllerRegistry = IControllerRegistry(_controllerRegistry);\n    }\n\n    // Provides metadata value for the opensea wallet. Must be set at construct time\n    // Source: https://www.reddit.com/r/ethdev/comments/q4j5bf/contracturi_not_reflected_in_opensea/\n    function contractURI() public view returns (string memory) {\n        return _contractURI;\n    }\n\n    // Note that OpenSea does not currently update contract metadata when this value is changed. - Nov 2021\n    function setContractURI(string memory newContractURI) public onlyOwner {\n        _contractURI = newContractURI;\n    }\n\n    /**\n     * @param _podId The pod id number\n     * @param _newController The address of the new controller\n     */\n    function migrateMemberController(uint256 _podId, address _newController)\n        external\n    {\n        require(_newController != address(0), \"Invalid address\");\n        require(\n            msg.sender == memberController[_podId],\n            \"Invalid migrate controller\"\n        );\n        require(\n            controllerRegistry.isRegistered(_newController),\n            \"Controller not registered\"\n        );\n\n        memberController[_podId] = _newController;\n        emit MigrateMemberController(_podId, _newController);\n    }\n\n    function getNextAvailablePodId() external view returns (uint256) {\n        return nextAvailablePodId;\n    }\n\n    function setUri(string memory uri) external onlyOwner {\n        _setURI(uri);\n    }\n\n    /**\n     * @param _account The account address to assign the membership token to\n     * @param _id The membership token id to mint\n     * @param data Passes a flag for initial creation event\n     */\n    function mint(\n        address _account,\n        uint256 _id,\n        bytes memory data\n    ) external {\n        _mint(_account, _id, 1, data);\n    }\n\n    /**\n     * @param _accounts The account addresses to assign the membership tokens to\n     * @param _id The membership token id to mint\n     * @param data Passes a flag for an initial creation event\n     */\n    function mintSingleBatch(\n        address[] memory _accounts,\n        uint256 _id,\n        bytes memory data\n    ) public {\n        for (uint256 index = 0; index < _accounts.length; index += 1) {\n            _mint(_accounts[index], _id, 1, data);\n        }\n    }\n\n    /**\n     * @param _accounts The account addresses to burn the membership tokens from\n     * @param _id The membership token id to burn\n     */\n    function burnSingleBatch(address[] memory _accounts, uint256 _id) public {\n        for (uint256 index = 0; index < _accounts.length; index += 1) {\n            _burn(_accounts[index], _id, 1);\n        }\n    }\n\n    function createPod(address[] memory _accounts, bytes memory data)\n        external\n        returns (uint256)\n    {\n        uint256 id = nextAvailablePodId;\n        nextAvailablePodId += 1;\n\n        require(\n            controllerRegistry.isRegistered(msg.sender),\n            \"Controller not registered\"\n        );\n\n        memberController[id] = msg.sender;\n\n        if (_accounts.length != 0) {\n            mintSingleBatch(_accounts, id, data);\n        }\n\n        return id;\n    }\n\n    /**\n     * @param _account The account address holding the membership token to destroy\n     * @param _id The id of the membership token to destroy\n     */\n    function burn(address _account, uint256 _id) external {\n        _burn(_account, _id, 1);\n    }\n\n    // this hook gets called before every token event including mint and burn\n    /**\n     * @param operator The account address that initiated the action\n     * @param from The account address recieveing the membership token\n     * @param to The account address sending the membership token\n     * @param ids An array of membership token ids to be transfered\n     * @param amounts The amount of each membership token type to transfer\n     * @param data Passes a flag for an initial creation event\n     */\n    function _beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal override {\n        // use first id to lookup controller\n        address controller = memberController[ids[0]];\n        require(controller != address(0), \"Pod doesn't exist\");\n\n        for (uint256 i = 0; i < ids.length; i += 1) {\n            // check if recipient is already member\n            if (to != address(0)) {\n                require(balanceOf(to, ids[i]) == 0, \"User is already member\");\n            }\n            // verify all ids use same controller\n            require(\n                memberController[ids[i]] == controller,\n                \"Ids have different controllers\"\n            );\n        }\n\n        // perform orca token transfer validations\n        IControllerBase(controller).beforeTokenTransfer(\n            operator,\n            from,\n            to,\n            ids,\n            amounts,\n            data\n        );\n    }\n}\n"
    },
    "lib/openzeppelin-contracts/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 functionCallWithValue(target, data, 0, \"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        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, 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        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or 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            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\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            /// @solidity memory-safe-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"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/ERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC1155.sol\";\nimport \"./IERC1155Receiver.sol\";\nimport \"./extensions/IERC1155MetadataURI.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of the basic standard multi-token.\n * See https://eips.ethereum.org/EIPS/eip-1155\n * Originally based on code by Enjin: https://github.com/enjin/erc-1155\n *\n * _Available since v3.1._\n */\ncontract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {\n    using Address for address;\n\n    // Mapping from token ID to account balances\n    mapping(uint256 => mapping(address => uint256)) private _balances;\n\n    // Mapping from account to operator approvals\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json\n    string private _uri;\n\n    /**\n     * @dev See {_setURI}.\n     */\n    constructor(string memory uri_) {\n        _setURI(uri_);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return\n            interfaceId == type(IERC1155).interfaceId ||\n            interfaceId == type(IERC1155MetadataURI).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev See {IERC1155MetadataURI-uri}.\n     *\n     * This implementation returns the same URI for *all* token types. It relies\n     * on the token type ID substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * Clients calling this function must replace the `\\{id\\}` substring with the\n     * actual token type ID.\n     */\n    function uri(uint256) public view virtual override returns (string memory) {\n        return _uri;\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {\n        require(account != address(0), \"ERC1155: address zero is not a valid owner\");\n        return _balances[id][account];\n    }\n\n    /**\n     * @dev See {IERC1155-balanceOfBatch}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)\n        public\n        view\n        virtual\n        override\n        returns (uint256[] memory)\n    {\n        require(accounts.length == ids.length, \"ERC1155: accounts and ids length mismatch\");\n\n        uint256[] memory batchBalances = new uint256[](accounts.length);\n\n        for (uint256 i = 0; i < accounts.length; ++i) {\n            batchBalances[i] = balanceOf(accounts[i], ids[i]);\n        }\n\n        return batchBalances;\n    }\n\n    /**\n     * @dev See {IERC1155-setApprovalForAll}.\n     */\n    function setApprovalForAll(address operator, bool approved) public virtual override {\n        _setApprovalForAll(_msgSender(), operator, approved);\n    }\n\n    /**\n     * @dev See {IERC1155-isApprovedForAll}.\n     */\n    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {\n        return _operatorApprovals[account][operator];\n    }\n\n    /**\n     * @dev See {IERC1155-safeTransferFrom}.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) public virtual override {\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: caller is not token owner nor approved\"\n        );\n        _safeTransferFrom(from, to, id, amount, data);\n    }\n\n    /**\n     * @dev See {IERC1155-safeBatchTransferFrom}.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) public virtual override {\n        require(\n            from == _msgSender() || isApprovedForAll(from, _msgSender()),\n            \"ERC1155: caller is not token owner nor approved\"\n        );\n        _safeBatchTransferFrom(from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function _safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) internal virtual {\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n        address operator = _msgSender();\n        uint256[] memory ids = _asSingletonArray(id);\n        uint256[] memory amounts = _asSingletonArray(amount);\n\n        _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        uint256 fromBalance = _balances[id][from];\n        require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n        unchecked {\n            _balances[id][from] = fromBalance - amount;\n        }\n        _balances[id][to] += amount;\n\n        emit TransferSingle(operator, from, to, id, amount);\n\n        _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function _safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n        require(to != address(0), \"ERC1155: transfer to the zero address\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        for (uint256 i = 0; i < ids.length; ++i) {\n            uint256 id = ids[i];\n            uint256 amount = amounts[i];\n\n            uint256 fromBalance = _balances[id][from];\n            require(fromBalance >= amount, \"ERC1155: insufficient balance for transfer\");\n            unchecked {\n                _balances[id][from] = fromBalance - amount;\n            }\n            _balances[id][to] += amount;\n        }\n\n        emit TransferBatch(operator, from, to, ids, amounts);\n\n        _afterTokenTransfer(operator, from, to, ids, amounts, data);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Sets a new URI for all token types, by relying on the token type ID\n     * substitution mechanism\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].\n     *\n     * By this mechanism, any occurrence of the `\\{id\\}` substring in either the\n     * URI or any of the amounts in the JSON file at said URI will be replaced by\n     * clients with the token type ID.\n     *\n     * For example, the `https://token-cdn-domain/\\{id\\}.json` URI would be\n     * interpreted by clients as\n     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`\n     * for token type ID 0x4cce0.\n     *\n     * See {uri}.\n     *\n     * Because these URIs cannot be meaningfully represented by the {URI} event,\n     * this function emits no events.\n     */\n    function _setURI(string memory newuri) internal virtual {\n        _uri = newuri;\n    }\n\n    /**\n     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function _mint(\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) internal virtual {\n        require(to != address(0), \"ERC1155: mint to the zero address\");\n\n        address operator = _msgSender();\n        uint256[] memory ids = _asSingletonArray(id);\n        uint256[] memory amounts = _asSingletonArray(amount);\n\n        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        _balances[id][to] += amount;\n        emit TransferSingle(operator, address(0), to, id, amount);\n\n        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function _mintBatch(\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {\n        require(to != address(0), \"ERC1155: mint to the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        for (uint256 i = 0; i < ids.length; i++) {\n            _balances[ids[i]][to] += amounts[i];\n        }\n\n        emit TransferBatch(operator, address(0), to, ids, amounts);\n\n        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);\n\n        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens of token type `id` from `from`\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `from` must have at least `amount` tokens of token type `id`.\n     */\n    function _burn(\n        address from,\n        uint256 id,\n        uint256 amount\n    ) internal virtual {\n        require(from != address(0), \"ERC1155: burn from the zero address\");\n\n        address operator = _msgSender();\n        uint256[] memory ids = _asSingletonArray(id);\n        uint256[] memory amounts = _asSingletonArray(amount);\n\n        _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n        uint256 fromBalance = _balances[id][from];\n        require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n        unchecked {\n            _balances[id][from] = fromBalance - amount;\n        }\n\n        emit TransferSingle(operator, from, address(0), id, amount);\n\n        _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n    }\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     */\n    function _burnBatch(\n        address from,\n        uint256[] memory ids,\n        uint256[] memory amounts\n    ) internal virtual {\n        require(from != address(0), \"ERC1155: burn from the zero address\");\n        require(ids.length == amounts.length, \"ERC1155: ids and amounts length mismatch\");\n\n        address operator = _msgSender();\n\n        _beforeTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n\n        for (uint256 i = 0; i < ids.length; i++) {\n            uint256 id = ids[i];\n            uint256 amount = amounts[i];\n\n            uint256 fromBalance = _balances[id][from];\n            require(fromBalance >= amount, \"ERC1155: burn amount exceeds balance\");\n            unchecked {\n                _balances[id][from] = fromBalance - amount;\n            }\n        }\n\n        emit TransferBatch(operator, from, address(0), ids, amounts);\n\n        _afterTokenTransfer(operator, from, address(0), ids, amounts, \"\");\n    }\n\n    /**\n     * @dev Approve `operator` to operate on all of `owner` tokens\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function _setApprovalForAll(\n        address owner,\n        address operator,\n        bool approved\n    ) internal virtual {\n        require(owner != operator, \"ERC1155: setting approval status for self\");\n        _operatorApprovals[owner][operator] = approved;\n        emit ApprovalForAll(owner, operator, approved);\n    }\n\n    /**\n     * @dev Hook that is called before any token transfer. This includes minting\n     * and burning, as well as batched variants.\n     *\n     * The same hook is called on both single and batched variants. For single\n     * transfers, the length of the `ids` and `amounts` arrays will be 1.\n     *\n     * Calling conditions (for each `id` and `amount` pair):\n     *\n     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * of token type `id` will be  transferred to `to`.\n     * - When `from` is zero, `amount` tokens of token type `id` will be minted\n     * for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n     * will be burned.\n     * - `from` and `to` are never both zero.\n     * - `ids` and `amounts` have the same, non-zero length.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any token transfer. This includes minting\n     * and burning, as well as batched variants.\n     *\n     * The same hook is called on both single and batched variants. For single\n     * transfers, the length of the `id` and `amount` arrays will be 1.\n     *\n     * Calling conditions (for each `id` and `amount` pair):\n     *\n     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * of token type `id` will be  transferred to `to`.\n     * - When `from` is zero, `amount` tokens of token type `id` will be minted\n     * for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`\n     * will be burned.\n     * - `from` and `to` are never both zero.\n     * - `ids` and `amounts` have the same, non-zero length.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual {}\n\n    function _doSafeTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes memory data\n    ) private {\n        if (to.isContract()) {\n            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {\n                if (response != IERC1155Receiver.onERC1155Received.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _doSafeBatchTransferAcceptanceCheck(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) private {\n        if (to.isContract()) {\n            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (\n                bytes4 response\n            ) {\n                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {\n                    revert(\"ERC1155: ERC1155Receiver rejected tokens\");\n                }\n            } catch Error(string memory reason) {\n                revert(reason);\n            } catch {\n                revert(\"ERC1155: transfer to non ERC1155Receiver implementer\");\n            }\n        }\n    }\n\n    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {\n        uint256[] memory array = new uint256[](1);\n        array[0] = element;\n\n        return array;\n    }\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Supply.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC1155/extensions/ERC1155Supply.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1155.sol\";\n\n/**\n * @dev Extension of ERC1155 that adds tracking of total supply per id.\n *\n * Useful for scenarios where Fungible and Non-fungible tokens have to be\n * clearly identified. Note: While a totalSupply of 1 might mean the\n * corresponding is an NFT, there is no guarantees that no other token with the\n * same id are not going to be minted.\n */\nabstract contract ERC1155Supply is ERC1155 {\n    mapping(uint256 => uint256) private _totalSupply;\n\n    /**\n     * @dev Total amount of tokens in with a given id.\n     */\n    function totalSupply(uint256 id) public view virtual returns (uint256) {\n        return _totalSupply[id];\n    }\n\n    /**\n     * @dev Indicates whether any token exist with a given id, or not.\n     */\n    function exists(uint256 id) public view virtual returns (bool) {\n        return ERC1155Supply.totalSupply(id) > 0;\n    }\n\n    /**\n     * @dev See {ERC1155-_beforeTokenTransfer}.\n     */\n    function _beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) internal virtual override {\n        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);\n\n        if (from == address(0)) {\n            for (uint256 i = 0; i < ids.length; ++i) {\n                _totalSupply[ids[i]] += amounts[i];\n            }\n        }\n\n        if (to == address(0)) {\n            for (uint256 i = 0; i < ids.length; ++i) {\n                uint256 id = ids[i];\n                uint256 amount = amounts[i];\n                uint256 supply = _totalSupply[id];\n                require(supply >= amount, \"ERC1155: burn amount exceeds totalSupply\");\n                unchecked {\n                    _totalSupply[id] = supply - amount;\n                }\n            }\n        }\n    }\n}\n"
    },
    "contracts/interfaces/IControllerBase.sol": {
      "content": "pragma solidity ^0.8.7;\n\ninterface IControllerBase {\n    /**\n     * @param operator The account address that initiated the action\n     * @param from The account address sending the membership token\n     * @param to The account address recieving the membership token\n     * @param ids An array of membership token ids to be transfered\n     * @param amounts The amount of each membership token type to transfer\n     * @param data Arbitrary data\n     */\n    function beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts,\n        bytes memory data\n    ) external;\n\n    function updatePodState(\n        uint256 _podId,\n        address _podAdmin,\n        address _safeAddress\n    ) external;\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n    /**\n     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n     */\n    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n    /**\n     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n     * transfers.\n     */\n    event TransferBatch(\n        address indexed operator,\n        address indexed from,\n        address indexed to,\n        uint256[] ids,\n        uint256[] values\n    );\n\n    /**\n     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n     * `approved`.\n     */\n    event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n    /**\n     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n     *\n     * If an {URI} event was emitted for `id`, the standard\n     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n     * returned by {IERC1155MetadataURI-uri}.\n     */\n    event URI(string value, uint256 indexed id);\n\n    /**\n     * @dev Returns the amount of tokens of token type `id` owned by `account`.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function balanceOf(address account, uint256 id) external view returns (uint256);\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n     *\n     * Requirements:\n     *\n     * - `accounts` and `ids` must have the same length.\n     */\n    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)\n        external\n        view\n        returns (uint256[] memory);\n\n    /**\n     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n     *\n     * Emits an {ApprovalForAll} event.\n     *\n     * Requirements:\n     *\n     * - `operator` cannot be the caller.\n     */\n    function setApprovalForAll(address operator, bool approved) external;\n\n    /**\n     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n     *\n     * See {setApprovalForAll}.\n     */\n    function isApprovedForAll(address account, address operator) external view returns (bool);\n\n    /**\n     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n     *\n     * Emits a {TransferSingle} event.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n     * - `from` must have a balance of tokens of type `id` of at least `amount`.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n     * acceptance magic value.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 id,\n        uint256 amount,\n        bytes calldata data\n    ) external;\n\n    /**\n     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n     *\n     * Emits a {TransferBatch} event.\n     *\n     * Requirements:\n     *\n     * - `ids` and `amounts` must have the same length.\n     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n     * acceptance magic value.\n     */\n    function safeBatchTransferFrom(\n        address from,\n        address to,\n        uint256[] calldata ids,\n        uint256[] calldata amounts,\n        bytes calldata data\n    ) external;\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155Receiver.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n    /**\n     * @dev Handles the receipt of a single ERC1155 token type. This function is\n     * called at the end of a `safeTransferFrom` after the balance has been updated.\n     *\n     * NOTE: To accept the transfer, this must return\n     * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n     * (i.e. 0xf23a6e61, or its own function selector).\n     *\n     * @param operator The address which initiated the transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param id The ID of the token being transferred\n     * @param value The amount of tokens being transferred\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n     */\n    function onERC1155Received(\n        address operator,\n        address from,\n        uint256 id,\n        uint256 value,\n        bytes calldata data\n    ) external returns (bytes4);\n\n    /**\n     * @dev Handles the receipt of a multiple ERC1155 token types. This function\n     * is called at the end of a `safeBatchTransferFrom` after the balances have\n     * been updated.\n     *\n     * NOTE: To accept the transfer(s), this must return\n     * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n     * (i.e. 0xbc197c81, or its own function selector).\n     *\n     * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n     * @param from The address which previously owned the token\n     * @param ids An array containing ids of each token being transferred (order and length must match values array)\n     * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n     * @param data Additional data with no specified format\n     * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n     */\n    function onERC1155BatchReceived(\n        address operator,\n        address from,\n        uint256[] calldata ids,\n        uint256[] calldata values,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n    /**\n     * @dev Returns the URI for token type `id`.\n     *\n     * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n     * clients with the actual token type ID.\n     */\n    function uri(uint256 id) external view returns (string memory);\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
    },
    "contracts/interfaces/IControllerV1.sol": {
      "content": "pragma solidity ^0.8.7;\n\nimport \"./IControllerBase.sol\";\n\ninterface IControllerV1 is IControllerBase {\n    function updatePodEnsRegistrar(address _podEnsRegistrar) external;\n\n    /**\n     * @param _members The addresses of the members of the pod\n     * @param threshold The number of members that are required to sign a transaction\n     * @param _admin The address of the pod admin\n     * @param _label label hash of pod name (i.e labelhash('mypod'))\n     * @param _ensString string of pod ens name (i.e.'mypod.pod.xyz')\n     */\n    function createPod(\n        address[] memory _members,\n        uint256 threshold,\n        address _admin,\n        bytes32 _label,\n        string memory _ensString,\n        uint256 expectedPodId,\n        string memory _imageUrl\n    ) external;\n\n    /**\n     * @dev Used to create a pod with an existing safe\n     * @dev Will automatically distribute membership NFTs to current safe members\n     * @param _admin The address of the pod admin\n     * @param _safe The address of existing safe\n     * @param _label label hash of pod name (i.e labelhash('mypod'))\n     * @param _ensString string of pod ens name (i.e.'mypod.pod.xyz')\n     */\n    function createPodWithSafe(\n        address _admin,\n        address _safe,\n        bytes32 _label,\n        string memory _ensString,\n        uint256 expectedPodId,\n        string memory _imageUrl\n    ) external;\n\n    function podIdToSafe(uint256 _podId) external view returns (address);\n\n    /**\n     * @dev Allows admin to unlock the safe modules and allow them to be edited by members\n     * @param _podId The id number of the pod\n     * @param _isLocked true - pod modules cannot be added/removed\n     */\n    function setPodModuleLock(uint256 _podId, bool _isLocked) external;\n\n    /**\n     * @param _podId The id number of the pod\n     * @param _isTransferLocked The address of the new pod admin\n     */\n    function setPodTransferLock(uint256 _podId, bool _isTransferLocked)\n        external;\n\n    /**\n     * @param _podId The id number of the pod\n     * @param _newAdmin The address of the new pod admin\n     */\n    function updatePodAdmin(uint256 _podId, address _newAdmin) external;\n\n    /**\n     * @dev This will nullify all pod state on this controller\n     * @dev Update state on _newController\n     * @dev Update controller to _newController in Safe and MemberToken\n     * @param _podId The id number of the pod\n     * @param _newController The address of the new pod controller\n     * @param _prevModule The module that points to the orca module in the safe's ModuleManager linked list\n     */\n    function migratePodController(\n        uint256 _podId,\n        address _newController,\n        address _prevModule\n    ) external;\n\n    function ejectSafe(\n        uint256 podId,\n        bytes32 label,\n        address previousModule\n    ) external;\n}\n"
    },
    "contracts/MultiCreateV1.sol": {
      "content": "pragma solidity ^0.8.7;\nimport \"./interfaces/IControllerV1.sol\";\nimport \"./interfaces/IMemberToken.sol\";\n\n/* solhint-disable indent */\n\ncontract MultiCreateV1 {\n    IMemberToken immutable memberToken;\n\n    constructor(address _memberToken) {\n        memberToken = IMemberToken(_memberToken);\n    }\n\n    struct AdminPointer {\n        uint256 podId;\n        address pointer;\n    }\n\n    function createPods(\n        IControllerV1 _controller,\n        address[][] memory _members,\n        uint256[] calldata _thresholds,\n        address[] memory _admins,\n        bytes32[] memory _labels,\n        string[] memory _ensStrings,\n        string[] memory _imageUrls\n    ) public returns (address[] memory) {\n        uint256 numPods = _thresholds.length;\n        require(_members.length == numPods, \"incorrect members array\");\n        require(_labels.length == numPods, \"incorrect labels array\");\n        require(_ensStrings.length == numPods, \"incorrect ensStrings array\");\n        require(_imageUrls.length == numPods, \"incorrect imageUrls array\");\n\n        uint256 nextPodId = memberToken.getNextAvailablePodId();\n\n        /*\n            When creating multiple pods at the same time, there is a case where one pod may be a dependancy of another\n            createPods -> PodA, PodB, PodC\n            PodB.members[address(0x1337), address(PodA) // doesn't exist yet]\n            since PodA doesn't exist at create time we need a placeholder\n            \n            when deploying the array of pods we use newPods as a cache \n            as each pod gets deployed we add the address to newPods\n            newPods = [address(0), address(PodA)];\n            PodB.members[address(0x1337), address(1) // we know to check the cache]\n\n            because we can't rely on address(0) we have to index the cache at 1\n        */\n\n        // 1 indexing to avoid relying on address(0)\n        address[] memory newPods = new address[](numPods + 1);\n        AdminPointer[] memory tempAdmin = new AdminPointer[](numPods + 1);\n\n        for (uint256 i = 0; i < numPods; i++) {\n            // if the numerical version of admin address is less than numPods + 1 and not address(0) its a pointer\n            if (\n                uint256(uint160(_admins[i])) <= numPods + 1 &&\n                _admins[i] != address(0)\n            ) {\n                // store the admin pointer\n                tempAdmin[i] = AdminPointer(nextPodId + i, _admins[i]);\n                // temperarily overwrite admin with this address\n                _admins[i] = address(this);\n            }\n\n            for (uint256 j = 0; j < _members[i].length; j++) {\n                // if the numerical version of member address is less than numPods + 1 its a pointer\n                if (uint256(uint160(_members[i][j])) <= numPods + 1) {\n                    // pointer must be under the current pod index\n                    require(\n                        uint256(uint160(_members[i][j])) < i + 1,\n                        \"Member dependency bad ordering\"\n                    );\n                    // overwrite member with new pod address\n                    _members[i][j] = newPods[uint256(uint160(_members[i][j]))];\n                }\n            }\n\n            _controller.createPod(\n                _members[i],\n                _thresholds[i],\n                _admins[i],\n                _labels[i],\n                _ensStrings[i],\n                nextPodId + i,\n                _imageUrls[i]\n            );\n            // store new pods with 1 index\n            newPods[i + 1] = _controller.podIdToSafe(nextPodId + (i));\n        }\n\n        // iterate through all of the stored admin pointers and transfer admin to the destination pod\n        for (uint256 i = 0; i < tempAdmin.length; i++) {\n            AdminPointer memory adminPointer = tempAdmin[i];\n            // if pointer is set\n            if (adminPointer.pointer != address(0)) {\n                _controller.updatePodAdmin(\n                    adminPointer.podId,\n                    newPods[uint256(uint160(adminPointer.pointer))]\n                );\n            }\n        }\n\n        return newPods;\n    }\n}\n"
    },
    "contracts/interfaces/IMemberToken.sol": {
      "content": "pragma solidity ^0.8.7;\n\nimport \"lib/openzeppelin-contracts/contracts/token/ERC1155/IERC1155.sol\";\n\ninterface IMemberToken is IERC1155 {\n    /**\n     * @dev Total amount of tokens in with a given id.\n     */\n    function totalSupply(uint256 id) external view returns (uint256);\n\n    /**\n     * @dev Indicates weither any token exist with a given id, or not.\n     */\n    function exists(uint256 id) external view returns (bool);\n\n    function getNextAvailablePodId() external view returns (uint256);\n\n    /**\n     * @param _podId The pod id number\n     * @param _newController The address of the new controller\n     */\n    function migrateMemberController(uint256 _podId, address _newController)\n        external;\n\n    /**\n     * @param _account The account address to transfer the membership token to\n     * @param _id The membership token id to mint\n     * @param data Arbitrary data\n     */\n    function mint(\n        address _account,\n        uint256 _id,\n        bytes memory data\n    ) external;\n\n    /**\n     * @param _accounts The account addresses to transfer the membership tokens to\n     * @param _id The membership token id to mint\n     * @param data Arbitrary data\n     */\n    function mintSingleBatch(\n        address[] memory _accounts,\n        uint256 _id,\n        bytes memory data\n    ) external;\n\n    function burnSingleBatch(address[] memory _accounts, uint256 _id) external;\n\n    function createPod(address[] memory _accounts, bytes memory data)\n        external\n        returns (uint256);\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/access/AccessControl.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        Strings.toHexString(account),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/access/IAccessControl.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/utils/Strings.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n}\n"
    },
    "contracts/ControllerV1.sol": {
      "content": "pragma solidity ^0.8.7;\n\n/* solhint-disable indent */\n\nimport \"lib/ens-contracts/contracts/registry/ENS.sol\";\nimport \"lib/ens-contracts/contracts/registry/ReverseRegistrar.sol\";\nimport \"lib/ens-contracts/contracts/resolvers/Resolver.sol\";\nimport \"lib/openzeppelin-contracts/contracts/access/Ownable.sol\";\nimport \"lib/openzeppelin-contracts/contracts/utils/Strings.sol\";\nimport \"./interfaces/IControllerV1.sol\";\nimport \"./interfaces/IMemberToken.sol\";\nimport \"./interfaces/IControllerRegistry.sol\";\nimport \"./SafeTeller.sol\";\nimport \"./ens/IPodEnsRegistrar.sol\";\n\ncontract ControllerV1 is IControllerV1, SafeTeller, Ownable {\n    event CreatePod(uint256 podId, address safe, address admin, string ensName);\n    event UpdatePodAdmin(uint256 podId, address admin);\n    event DeregisterPod(uint256 podId);\n\n    IMemberToken public immutable memberToken;\n    IControllerRegistry public immutable controllerRegistry;\n    IPodEnsRegistrar public podEnsRegistrar;\n\n    string public constant VERSION = \"1.3.0\";\n\n    mapping(address => uint256) public safeToPodId;\n    mapping(uint256 => address) public override podIdToSafe;\n    mapping(uint256 => address) public podAdmin;\n    mapping(uint256 => bool) public isTransferLocked;\n\n    uint8 internal constant CREATE_EVENT = 0x01;\n\n    /**\n     * @dev Will instantiate safe teller with gnosis master and proxy addresses\n     * @param _memberToken The address of the MemberToken contract\n     * @param _controllerRegistry The address of the ControllerRegistry contract\n     * @param _proxyFactoryAddress The proxy factory address\n     * @param _gnosisMasterAddress The gnosis master address\n     */\n    constructor(\n        address _memberToken,\n        address _controllerRegistry,\n        address _proxyFactoryAddress,\n        address _gnosisMasterAddress,\n        address _podEnsRegistrar,\n        address _fallbackHandlerAddress\n    )\n        SafeTeller(\n            _proxyFactoryAddress,\n            _gnosisMasterAddress,\n            _fallbackHandlerAddress\n        )\n    {\n        require(_memberToken != address(0), \"Invalid address\");\n        require(_controllerRegistry != address(0), \"Invalid address\");\n        require(_proxyFactoryAddress != address(0), \"Invalid address\");\n        require(_gnosisMasterAddress != address(0), \"Invalid address\");\n        require(_podEnsRegistrar != address(0), \"Invalid address\");\n        require(_fallbackHandlerAddress != address(0), \"Invalid address\");\n\n        memberToken = IMemberToken(_memberToken);\n        controllerRegistry = IControllerRegistry(_controllerRegistry);\n        podEnsRegistrar = IPodEnsRegistrar(_podEnsRegistrar);\n    }\n\n    function updatePodEnsRegistrar(address _podEnsRegistrar)\n        external\n        override\n        onlyOwner\n    {\n        require(_podEnsRegistrar != address(0), \"Invalid address\");\n        podEnsRegistrar = IPodEnsRegistrar(_podEnsRegistrar);\n    }\n\n    /**\n     * @param _members The addresses of the members of the pod\n     * @param threshold The number of members that are required to sign a transaction\n     * @param _admin The address of the pod admin\n     * @param _label label hash of pod name (i.e labelhash('mypod'))\n     * @param _ensString string of pod ens name (i.e.'mypod.pod.xyz')\n     */\n    function createPod(\n        address[] memory _members,\n        uint256 threshold,\n        address _admin,\n        bytes32 _label,\n        string memory _ensString,\n        uint256 expectedPodId,\n        string memory _imageUrl\n    ) external override {\n        address safe = createSafe(_members, threshold);\n\n        _createPod(\n            _members,\n            safe,\n            _admin,\n            _label,\n            _ensString,\n            expectedPodId,\n            _imageUrl\n        );\n    }\n\n    /**\n     * @dev Used to create a pod with an existing safe\n     * @dev Will automatically distribute membership NFTs to current safe members\n     * @param _admin The address of the pod admin\n     * @param _safe The address of existing safe\n     * @param _label label hash of pod name (i.e labelhash('mypod'))\n     * @param _ensString string of pod ens name (i.e.'mypod.pod.xyz')\n     */\n    function createPodWithSafe(\n        address _admin,\n        address _safe,\n        bytes32 _label,\n        string memory _ensString,\n        uint256 expectedPodId,\n        string memory _imageUrl\n    ) external override {\n        require(_safe != address(0), \"invalid safe address\");\n        require(safeToPodId[_safe] == 0, \"safe already in use\");\n        require(isSafeModuleEnabled(_safe), \"safe module must be enabled\");\n        require(\n            isSafeMember(_safe, msg.sender) || msg.sender == _safe,\n            \"caller must be safe or member\"\n        );\n\n        address[] memory members = getSafeMembers(_safe);\n\n        _createPod(\n            members,\n            _safe,\n            _admin,\n            _label,\n            _ensString,\n            expectedPodId,\n            _imageUrl\n        );\n    }\n\n    /**\n     * @param _members The addresses of the members of the pod\n     * @param _admin The address of the pod admin\n     * @param _safe The address of existing safe\n     * @param _label label hash of pod name (i.e labelhash('mypod'))\n     * @param _ensString string of pod ens name (i.e.'mypod.pod.xyz')\n     */\n    function _createPod(\n        address[] memory _members,\n        address _safe,\n        address _admin,\n        bytes32 _label,\n        string memory _ensString,\n        uint256 expectedPodId,\n        string memory _imageUrl\n    ) internal {\n        // add create event flag to token data\n        bytes memory data = new bytes(1);\n        data[0] = bytes1(uint8(CREATE_EVENT));\n\n        uint256 podId = memberToken.createPod(_members, data);\n        // The imageUrl has an expected pod ID, but we need to make sure it aligns with the actual pod ID\n        require(podId == expectedPodId, \"pod id didn't match, try again\");\n\n        emit CreatePod(podId, _safe, _admin, _ensString);\n        emit UpdatePodAdmin(podId, _admin);\n\n        if (_admin != address(0)) {\n            // will lock safe modules if admin exists\n            setModuleLock(_safe, true);\n            podAdmin[podId] = _admin;\n        }\n        podIdToSafe[podId] = _safe;\n        safeToPodId[_safe] = podId;\n\n        // setup pod ENS\n        address reverseRegistrar = podEnsRegistrar.registerPod(\n            _label,\n            _safe,\n            msg.sender\n        );\n        setupSafeReverseResolver(_safe, reverseRegistrar, _ensString);\n\n        // Node is how ENS identifies names, we need that to setText\n        bytes32 node = podEnsRegistrar.getEnsNode(_label);\n        podEnsRegistrar.setText(node, \"avatar\", _imageUrl);\n        podEnsRegistrar.setText(node, \"podId\", Strings.toString(podId));\n    }\n\n    /**\n     * @dev Allows admin to unlock the safe modules and allow them to be edited by members\n     * @param _podId The id number of the pod\n     * @param _isLocked true - pod modules cannot be added/removed\n     */\n    function setPodModuleLock(uint256 _podId, bool _isLocked)\n        external\n        override\n    {\n        require(\n            msg.sender == podAdmin[_podId],\n            \"Must be admin to set module lock\"\n        );\n        setModuleLock(podIdToSafe[_podId], _isLocked);\n    }\n\n    /**\n     * @param _podId The id number of the pod\n     * @param _newAdmin The address of the new pod admin\n     */\n    function updatePodAdmin(uint256 _podId, address _newAdmin)\n        external\n        override\n    {\n        address admin = podAdmin[_podId];\n        address safe = podIdToSafe[_podId];\n\n        require(safe != address(0), \"Pod doesn't exist\");\n\n        // if there is no admin it can only be added by safe\n        if (admin == address(0)) {\n            require(msg.sender == safe, \"Only safe can add new admin\");\n        } else {\n            require(msg.sender == admin, \"Only admin can update admin\");\n        }\n        // set module lock to true for non zero _newAdmin\n        setModuleLock(safe, _newAdmin != address(0));\n\n        podAdmin[_podId] = _newAdmin;\n\n        emit UpdatePodAdmin(_podId, _newAdmin);\n    }\n\n    /**\n     * @param _podId The id number of the pod\n     * @param _isTransferLocked The address of the new pod admin\n     */\n    function setPodTransferLock(uint256 _podId, bool _isTransferLocked)\n        external\n        override\n    {\n        address admin = podAdmin[_podId];\n        address safe = podIdToSafe[_podId];\n\n        // if no pod admin it can only be set by safe\n        if (admin == address(0)) {\n            require(msg.sender == safe, \"Only safe can set transfer lock\");\n        } else {\n            // if admin then it can be set by admin or safe\n            require(\n                msg.sender == admin || msg.sender == safe,\n                \"Only admin or safe can set transfer lock\"\n            );\n        }\n\n        // set podid to transfer lock bool\n        isTransferLocked[_podId] = _isTransferLocked;\n    }\n\n    /**\n     * @dev This will nullify all pod state on this controller\n     * @dev Update state on _newController\n     * @dev Update controller to _newController in Safe and MemberToken\n     * @param _podId The id number of the pod\n     * @param _newController The address of the new pod controller\n     * @param _prevModule The module that points to the orca module in the safe's ModuleManager linked list\n     */\n    function migratePodController(\n        uint256 _podId,\n        address _newController,\n        address _prevModule\n    ) external override {\n        require(_newController != address(0), \"Invalid address\");\n        require(\n            controllerRegistry.isRegistered(_newController),\n            \"Controller not registered\"\n        );\n\n        address admin = podAdmin[_podId];\n        address safe = podIdToSafe[_podId];\n\n        require(\n            msg.sender == admin || msg.sender == safe,\n            \"User not authorized\"\n        );\n\n        IControllerBase newController = IControllerBase(_newController);\n\n        // nullify current pod state\n        podAdmin[_podId] = address(0);\n        podIdToSafe[_podId] = address(0);\n        safeToPodId[safe] = 0;\n        // update controller in MemberToken\n        memberToken.migrateMemberController(_podId, _newController);\n        // update safe module to _newController\n        migrateSafeTeller(safe, _newController, _prevModule);\n        // update pod state in _newController\n        newController.updatePodState(_podId, admin, safe);\n    }\n\n    /**\n     * @dev This is called by another version of controller to migrate a pod to this version\n     * @dev Will only accept calls from registered controllers\n     * @dev Can only be called once.\n     * @param _podId The id number of the pod\n     * @param _podAdmin The address of the pod admin\n     * @param _safeAddress The address of the safe\n     */\n    function updatePodState(\n        uint256 _podId,\n        address _podAdmin,\n        address _safeAddress\n    ) external override {\n        require(_safeAddress != address(0), \"Invalid address\");\n        require(\n            controllerRegistry.isRegistered(msg.sender),\n            \"Controller not registered\"\n        );\n        require(\n            podAdmin[_podId] == address(0) &&\n                podIdToSafe[_podId] == address(0) &&\n                safeToPodId[_safeAddress] == 0,\n            \"Pod already exists\"\n        );\n        // if there is a pod admin, set state and lock modules\n        if (_podAdmin != address(0)) {\n            podAdmin[_podId] = _podAdmin;\n            setModuleLock(_safeAddress, true);\n        }\n        podIdToSafe[_podId] = _safeAddress;\n        safeToPodId[_safeAddress] = _podId;\n\n        setSafeTellerAsGuard(_safeAddress);\n\n        emit UpdatePodAdmin(_podId, _podAdmin);\n    }\n\n    /**\n     * Ejects a safe from the Orca ecosystem. Also handles clean up for safes\n     * that have already been ejected.\n     * Note that the reverse registry entry cannot be cleaned up if the safe has already been ejected.\n     * @param podId - ID of pod being ejected\n     * @param label - labelhash of pod ENS name, i.e., `labelhash(\"mypod\")`\n     * @param previousModule - previous module\n     */\n    function ejectSafe(\n        uint256 podId,\n        bytes32 label,\n        address previousModule\n    ) external override {\n        address safe = podIdToSafe[podId];\n        require(safe != address(0), \"pod not registered\");\n        address[] memory members = this.getSafeMembers(safe);\n\n        Resolver resolver = Resolver(podEnsRegistrar.resolver());\n        bytes32 node = podEnsRegistrar.getEnsNode(label);\n        address addr = resolver.addr(node);\n        require(addr == safe, \"safe and label didn't match\");\n        podEnsRegistrar.setText(node, \"avatar\", \"\");\n        podEnsRegistrar.setText(node, \"podId\", \"\");\n        podEnsRegistrar.setAddr(node, address(0));\n        podEnsRegistrar.register(label, address(0));\n\n        if (podAdmin[podId] != address(0)) {\n            require(msg.sender == podAdmin[podId], \"must be admin\");\n            setModuleLock(safe, false);\n        } else {\n            require(msg.sender == safe, \"tx must be sent from safe\");\n        }\n\n        // Also handles reverse registration clearing.\n        this.disableModule(\n            safe,\n            podEnsRegistrar.reverseRegistrar(),\n            previousModule,\n            address(this)\n        );\n\n        // This needs to happen before the burn to skip the transfer check.\n        podAdmin[podId] = address(0);\n        podIdToSafe[podId] = address(0);\n        safeToPodId[safe] = 0;\n\n        memberToken.burnSingleBatch(members, podId);\n\n        emit DeregisterPod(podId);\n    }\n\n    /**\n     * @param operator The address that initiated the action\n     * @param from The address sending the membership token\n     * @param to The address recieveing the membership token\n     * @param ids An array of membership token ids to be transfered\n     * @param data Passes a flag for an initial creation event\n     */\n    function beforeTokenTransfer(\n        address operator,\n        address from,\n        address to,\n        uint256[] memory ids,\n        uint256[] memory,\n        bytes memory data\n    ) external override {\n        require(msg.sender == address(memberToken), \"Not Authorized\");\n\n        // if create event than side effects have been pre-handled\n        // only recognise data flags from this controller\n        if (\n            operator == address(this) &&\n            data.length > 0 &&\n            uint8(data[0]) == CREATE_EVENT\n        ) return;\n\n        for (uint256 i = 0; i < ids.length; i += 1) {\n            uint256 podId = ids[i];\n            address safe = podIdToSafe[podId];\n            address admin = podAdmin[podId];\n\n            // If safe is 0'd, it means we're deregistering the pod, so we can skip check\n            if (safe == address(0) && to == address(0)) return;\n\n            if (from == address(0)) {\n                // mint event\n\n                // there are no rules operator must be admin, safe or controller\n                require(\n                    operator == safe ||\n                        operator == admin ||\n                        operator == address(this),\n                    \"No Rules Set\"\n                );\n\n                onMint(to, safe);\n            } else if (to == address(0)) {\n                // burn event\n\n                // there are no rules  operator must be admin, safe or controller\n                require(\n                    operator == safe ||\n                        operator == admin ||\n                        operator == address(this),\n                    \"No Rules Set\"\n                );\n\n                onBurn(from, safe);\n            } else {\n                // pod cannot be locked\n                require(\n                    isTransferLocked[podId] == false,\n                    \"Pod Is Transfer Locked\"\n                );\n                // transfer event\n                onTransfer(from, to, safe);\n            }\n        }\n    }\n}\n"
    },
    "lib/ens-contracts/contracts/registry/ENS.sol": {
      "content": "pragma solidity >=0.8.4;\n\ninterface ENS {\n    // Logged when the owner of a node assigns a new owner to a subnode.\n    event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\n\n    // Logged when the owner of a node transfers ownership to a new account.\n    event Transfer(bytes32 indexed node, address owner);\n\n    // Logged when the resolver for a node changes.\n    event NewResolver(bytes32 indexed node, address resolver);\n\n    // Logged when the TTL of a node changes\n    event NewTTL(bytes32 indexed node, uint64 ttl);\n\n    // Logged when an operator is added or removed.\n    event ApprovalForAll(\n        address indexed owner,\n        address indexed operator,\n        bool approved\n    );\n\n    function setRecord(\n        bytes32 node,\n        address owner,\n        address resolver,\n        uint64 ttl\n    ) external;\n\n    function setSubnodeRecord(\n        bytes32 node,\n        bytes32 label,\n        address owner,\n        address resolver,\n        uint64 ttl\n    ) external;\n\n    function setSubnodeOwner(\n        bytes32 node,\n        bytes32 label,\n        address owner\n    ) external returns (bytes32);\n\n    function setResolver(bytes32 node, address resolver) external;\n\n    function setOwner(bytes32 node, address owner) external;\n\n    function setTTL(bytes32 node, uint64 ttl) external;\n\n    function setApprovalForAll(address operator, bool approved) external;\n\n    function owner(bytes32 node) external view returns (address);\n\n    function resolver(bytes32 node) external view returns (address);\n\n    function ttl(bytes32 node) external view returns (uint64);\n\n    function recordExists(bytes32 node) external view returns (bool);\n\n    function isApprovedForAll(address owner, address operator)\n        external\n        view\n        returns (bool);\n}\n"
    },
    "lib/ens-contracts/contracts/registry/ReverseRegistrar.sol": {
      "content": "pragma solidity >=0.8.4;\n\nimport \"./ENS.sol\";\nimport \"./IReverseRegistrar.sol\";\nimport \"lib/openzeppelin-contracts/contracts/access/Ownable.sol\";\nimport \"../root/Controllable.sol\";\n\nabstract contract NameResolver {\n    function setName(bytes32 node, string memory name) public virtual;\n}\n\nbytes32 constant lookup = 0x3031323334353637383961626364656600000000000000000000000000000000;\n\nbytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\n\n// namehash('addr.reverse')\n\ncontract ReverseRegistrar is Ownable, Controllable, IReverseRegistrar {\n    ENS public immutable ens;\n    NameResolver public defaultResolver;\n\n    event ReverseClaimed(address indexed addr, bytes32 indexed node);\n\n    /**\n     * @dev Constructor\n     * @param ensAddr The address of the ENS registry.\n     */\n    constructor(ENS ensAddr) {\n        ens = ensAddr;\n\n        // Assign ownership of the reverse record to our deployer\n        ReverseRegistrar oldRegistrar = ReverseRegistrar(\n            ensAddr.owner(ADDR_REVERSE_NODE)\n        );\n        if (address(oldRegistrar) != address(0x0)) {\n            oldRegistrar.claim(msg.sender);\n        }\n    }\n\n    modifier authorised(address addr) {\n        require(\n            addr == msg.sender ||\n                controllers[msg.sender] ||\n                ens.isApprovedForAll(addr, msg.sender) ||\n                ownsContract(addr),\n            \"ReverseRegistrar: Caller is not a controller or authorised by address or the address itself\"\n        );\n        _;\n    }\n\n    function setDefaultResolver(address resolver) public override onlyOwner {\n        require(\n            address(resolver) != address(0),\n            \"ReverseRegistrar: Resolver address must not be 0\"\n        );\n        defaultResolver = NameResolver(resolver);\n    }\n\n    /**\n     * @dev Transfers ownership of the reverse ENS record associated with the\n     *      calling account.\n     * @param owner The address to set as the owner of the reverse record in ENS.\n     * @return The ENS node hash of the reverse record.\n     */\n    function claim(address owner) public override returns (bytes32) {\n        return claimForAddr(msg.sender, owner, address(defaultResolver));\n    }\n\n    /**\n     * @dev Transfers ownership of the reverse ENS record associated with the\n     *      calling account.\n     * @param addr The reverse record to set\n     * @param owner The address to set as the owner of the reverse record in ENS.\n     * @return The ENS node hash of the reverse record.\n     */\n    function claimForAddr(\n        address addr,\n        address owner,\n        address resolver\n    ) public override authorised(addr) returns (bytes32) {\n        bytes32 labelHash = sha3HexAddress(addr);\n        bytes32 reverseNode = keccak256(\n            abi.encodePacked(ADDR_REVERSE_NODE, labelHash)\n        );\n        emit ReverseClaimed(addr, reverseNode);\n        ens.setSubnodeRecord(ADDR_REVERSE_NODE, labelHash, owner, resolver, 0);\n        return reverseNode;\n    }\n\n    /**\n     * @dev Transfers ownership of the reverse ENS record associated with the\n     *      calling account.\n     * @param owner The address to set as the owner of the reverse record in ENS.\n     * @param resolver The address of the resolver to set; 0 to leave unchanged.\n     * @return The ENS node hash of the reverse record.\n     */\n    function claimWithResolver(address owner, address resolver)\n        public\n        override\n        returns (bytes32)\n    {\n        return claimForAddr(msg.sender, owner, resolver);\n    }\n\n    /**\n     * @dev Sets the `name()` record for the reverse ENS record associated with\n     * the calling account. First updates the resolver to the default reverse\n     * resolver if necessary.\n     * @param name The name to set for this address.\n     * @return The ENS node hash of the reverse record.\n     */\n    function setName(string memory name) public override returns (bytes32) {\n        return\n            setNameForAddr(\n                msg.sender,\n                msg.sender,\n                address(defaultResolver),\n                name\n            );\n    }\n\n    /**\n     * @dev Sets the `name()` record for the reverse ENS record associated with\n     * the account provided. First updates the resolver to the default reverse\n     * resolver if necessary.\n     * Only callable by controllers and authorised users\n     * @param addr The reverse record to set\n     * @param owner The owner of the reverse node\n     * @param name The name to set for this address.\n     * @return The ENS node hash of the reverse record.\n     */\n    function setNameForAddr(\n        address addr,\n        address owner,\n        address resolver,\n        string memory name\n    ) public override returns (bytes32) {\n        bytes32 node = claimForAddr(addr, owner, resolver);\n        NameResolver(resolver).setName(node, name);\n        return node;\n    }\n\n    /**\n     * @dev Returns the node hash for a given account's reverse records.\n     * @param addr The address to hash\n     * @return The ENS node hash.\n     */\n    function node(address addr) public pure override returns (bytes32) {\n        return\n            keccak256(\n                abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr))\n            );\n    }\n\n    /**\n     * @dev An optimised function to compute the sha3 of the lower-case\n     *      hexadecimal representation of an Ethereum address.\n     * @param addr The address to hash\n     * @return ret The SHA3 hash of the lower-case hexadecimal encoding of the\n     *         input address.\n     */\n    function sha3HexAddress(address addr) private pure returns (bytes32 ret) {\n        assembly {\n            for {\n                let i := 40\n            } gt(i, 0) {\n\n            } {\n                i := sub(i, 1)\n                mstore8(i, byte(and(addr, 0xf), lookup))\n                addr := div(addr, 0x10)\n                i := sub(i, 1)\n                mstore8(i, byte(and(addr, 0xf), lookup))\n                addr := div(addr, 0x10)\n            }\n\n            ret := keccak256(0, 40)\n        }\n    }\n\n    function ownsContract(address addr) internal view returns (bool) {\n        try Ownable(addr).owner() returns (address owner) {\n            return owner == msg.sender;\n        } catch {\n            return false;\n        }\n    }\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/Resolver.sol": {
      "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\";\nimport \"./profiles/IABIResolver.sol\";\nimport \"./profiles/IAddressResolver.sol\";\nimport \"./profiles/IAddrResolver.sol\";\nimport \"./profiles/IContentHashResolver.sol\";\nimport \"./profiles/IDNSRecordResolver.sol\";\nimport \"./profiles/IDNSZoneResolver.sol\";\nimport \"./profiles/IInterfaceResolver.sol\";\nimport \"./profiles/INameResolver.sol\";\nimport \"./profiles/IPubkeyResolver.sol\";\nimport \"./profiles/ITextResolver.sol\";\nimport \"./profiles/IExtendedResolver.sol\";\n\n/**\n * A generic resolver interface which includes all the functions including the ones deprecated\n */\ninterface Resolver is\n    IERC165,\n    IABIResolver,\n    IAddressResolver,\n    IAddrResolver,\n    IContentHashResolver,\n    IDNSRecordResolver,\n    IDNSZoneResolver,\n    IInterfaceResolver,\n    INameResolver,\n    IPubkeyResolver,\n    ITextResolver,\n    IExtendedResolver\n{\n    /* Deprecated events */\n    event ContentChanged(bytes32 indexed node, bytes32 hash);\n\n    function setABI(\n        bytes32 node,\n        uint256 contentType,\n        bytes calldata data\n    ) external;\n\n    function setAddr(bytes32 node, address addr) external;\n\n    function setAddr(\n        bytes32 node,\n        uint256 coinType,\n        bytes calldata a\n    ) external;\n\n    function setContenthash(bytes32 node, bytes calldata hash) external;\n\n    function setDnsrr(bytes32 node, bytes calldata data) external;\n\n    function setName(bytes32 node, string calldata _name) external;\n\n    function setPubkey(\n        bytes32 node,\n        bytes32 x,\n        bytes32 y\n    ) external;\n\n    function setText(\n        bytes32 node,\n        string calldata key,\n        string calldata value\n    ) external;\n\n    function setInterface(\n        bytes32 node,\n        bytes4 interfaceID,\n        address implementer\n    ) external;\n\n    function multicall(bytes[] calldata data)\n        external\n        returns (bytes[] memory results);\n\n    /* Deprecated functions */\n    function content(bytes32 node) external view returns (bytes32);\n\n    function multihash(bytes32 node) external view returns (bytes memory);\n\n    function setContent(bytes32 node, bytes32 hash) external;\n\n    function setMultihash(bytes32 node, bytes calldata hash) external;\n}\n"
    },
    "contracts/SafeTeller.sol": {
      "content": "pragma solidity ^0.8.7;\n\nimport \"lib/openzeppelin-contracts/contracts/utils/Address.sol\";\nimport \"./interfaces/IGnosisSafe.sol\";\nimport \"./interfaces/IGnosisSafeProxyFactory.sol\";\nimport {BaseGuard, Enum} from \"lib/safe-contracts/contracts/base/GuardManager.sol\";\n\ncontract SafeTeller is BaseGuard {\n    using Address for address;\n\n    // mainnet: 0x76E2cFc1F5Fa8F6a5b3fC4c8F4788F0116861F9B;\n    address public immutable proxyFactoryAddress;\n\n    // mainnet: 0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F;\n    address public immutable gnosisMasterAddress;\n    address public immutable fallbackHandlerAddress;\n\n    string public constant FUNCTION_SIG_SETUP =\n        \"setup(address[],uint256,address,bytes,address,address,uint256,address)\";\n    string public constant FUNCTION_SIG_EXEC =\n        \"execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)\";\n\n    string public constant FUNCTION_SIG_ENABLE = \"delegateSetup(address)\";\n\n    bytes4 public constant ENCODED_SIG_ENABLE_MOD =\n        bytes4(keccak256(\"enableModule(address)\"));\n    bytes4 public constant ENCODED_SIG_DISABLE_MOD =\n        bytes4(keccak256(\"disableModule(address,address)\"));\n    bytes4 public constant ENCODED_SIG_SET_GUARD =\n        bytes4(keccak256(\"setGuard(address)\"));\n\n    address internal constant SENTINEL = address(0x1);\n\n    // pods with admin have modules locked by default\n    mapping(address => bool) public areModulesLocked;\n\n    /**\n     * @param _proxyFactoryAddress The proxy factory address\n     * @param _gnosisMasterAddress The gnosis master address\n     */\n    constructor(\n        address _proxyFactoryAddress,\n        address _gnosisMasterAddress,\n        address _fallbackHanderAddress\n    ) {\n        proxyFactoryAddress = _proxyFactoryAddress;\n        gnosisMasterAddress = _gnosisMasterAddress;\n        fallbackHandlerAddress = _fallbackHanderAddress;\n    }\n\n    /**\n     * @param _safe The address of the safe\n     * @param _newSafeTeller The address of the new safe teller contract\n     */\n    function migrateSafeTeller(\n        address _safe,\n        address _newSafeTeller,\n        address _prevModule\n    ) internal {\n        // add new safeTeller\n        bytes memory enableData = abi.encodeWithSignature(\n            \"enableModule(address)\",\n            _newSafeTeller\n        );\n\n        bool enableSuccess = IGnosisSafe(_safe).execTransactionFromModule(\n            _safe,\n            0,\n            enableData,\n            IGnosisSafe.Operation.Call\n        );\n        require(enableSuccess, \"Migration failed on enable\");\n\n        // validate prevModule of current safe teller\n        (address[] memory moduleBuffer, ) = IGnosisSafe(_safe)\n            .getModulesPaginated(_prevModule, 1);\n        require(moduleBuffer[0] == address(this), \"incorrect prevModule\");\n\n        // disable current safeTeller\n        bytes memory disableData = abi.encodeWithSignature(\n            \"disableModule(address,address)\",\n            _prevModule,\n            address(this)\n        );\n\n        bool disableSuccess = IGnosisSafe(_safe).execTransactionFromModule(\n            _safe,\n            0,\n            disableData,\n            IGnosisSafe.Operation.Call\n        );\n        require(disableSuccess, \"Migration failed on disable\");\n    }\n\n    /**\n     * @dev sets the safeteller as safe guard, called after migration\n     * @param _safe The address of the safe\n     */\n    function setSafeTellerAsGuard(address _safe) internal {\n        bytes memory transferData = abi.encodeWithSignature(\n            \"setGuard(address)\",\n            address(this)\n        );\n\n        bool guardSuccess = IGnosisSafe(_safe).execTransactionFromModule(\n            _safe,\n            0,\n            transferData,\n            IGnosisSafe.Operation.Call\n        );\n        require(guardSuccess, \"Could not enable guard\");\n    }\n\n    function getSafeMembers(address safe)\n        public\n        view\n        returns (address[] memory)\n    {\n        return IGnosisSafe(safe).getOwners();\n    }\n\n    function isSafeModuleEnabled(address safe) public view returns (bool) {\n        return IGnosisSafe(safe).isModuleEnabled(address(this));\n    }\n\n    function isSafeMember(address safe, address member)\n        public\n        view\n        returns (bool)\n    {\n        return IGnosisSafe(safe).isOwner(member);\n    }\n\n    /**\n     * @param _owners The  addresses to be owners of the safe\n     * @param _threshold The number of owners that are required to sign a transaciton\n     * @return safeAddress The address of the new safe\n     */\n    function createSafe(address[] memory _owners, uint256 _threshold)\n        internal\n        returns (address safeAddress)\n    {\n        bytes memory data = abi.encodeWithSignature(\n            FUNCTION_SIG_ENABLE,\n            address(this)\n        );\n\n        // encode the setup call that will be called on the new proxy safe\n        // from the proxy factory\n        bytes memory setupData = abi.encodeWithSignature(\n            FUNCTION_SIG_SETUP,\n            _owners,\n            _threshold,\n            this,\n            data,\n            fallbackHandlerAddress,\n            address(0),\n            uint256(0),\n            address(0)\n        );\n\n        try\n            IGnosisSafeProxyFactory(proxyFactoryAddress).createProxy(\n                gnosisMasterAddress,\n                setupData\n            )\n        returns (address newSafeAddress) {\n            // add safe teller as guard\n            setSafeTellerAsGuard(newSafeAddress);\n\n            return newSafeAddress;\n        } catch (bytes memory) {\n            revert(\"Create Proxy With Data Failed\");\n        }\n    }\n\n    /**\n     * @param to The account address to add as an owner\n     * @param safe The address of the safe\n     */\n    function onMint(address to, address safe) internal {\n        uint256 threshold = IGnosisSafe(safe).getThreshold();\n\n        bytes memory data = abi.encodeWithSignature(\n            \"addOwnerWithThreshold(address,uint256)\",\n            to,\n            threshold\n        );\n\n        bool success = IGnosisSafe(safe).execTransactionFromModule(\n            safe,\n            0,\n            data,\n            IGnosisSafe.Operation.Call\n        );\n\n        require(success, \"Module Transaction Failed\");\n    }\n\n    /**\n     * @param from The address to be removed as an owner\n     * @param safe The address of the safe\n     */\n    function onBurn(address from, address safe) internal {\n        uint256 threshold = IGnosisSafe(safe).getThreshold();\n        address[] memory owners = IGnosisSafe(safe).getOwners();\n\n        //look for the address pointing to address from\n        address prevFrom = address(0);\n        for (uint256 i = 0; i < owners.length; i++) {\n            if (owners[i] == from) {\n                if (i == 0) {\n                    prevFrom = SENTINEL;\n                } else {\n                    prevFrom = owners[i - 1];\n                }\n            }\n        }\n        if (owners.length - 1 < threshold) threshold -= 1;\n        bytes memory data = abi.encodeWithSignature(\n            \"removeOwner(address,address,uint256)\",\n            prevFrom,\n            from,\n            threshold\n        );\n\n        bool success = IGnosisSafe(safe).execTransactionFromModule(\n            safe,\n            0,\n            data,\n            IGnosisSafe.Operation.Call\n        );\n        require(success, \"Module Transaction Failed\");\n    }\n\n    /**\n     * @param from The address being removed as an owner\n     * @param to The address being added as an owner\n     * @param safe The address of the safe\n     */\n    function onTransfer(\n        address from,\n        address to,\n        address safe\n    ) internal {\n        address[] memory owners = IGnosisSafe(safe).getOwners();\n\n        //look for the address pointing to address from\n        address prevFrom;\n        for (uint256 i = 0; i < owners.length; i++) {\n            if (owners[i] == from) {\n                if (i == 0) {\n                    prevFrom = SENTINEL;\n                } else {\n                    prevFrom = owners[i - 1];\n                }\n            }\n        }\n\n        bytes memory data = abi.encodeWithSignature(\n            \"swapOwner(address,address,address)\",\n            prevFrom,\n            from,\n            to\n        );\n\n        bool success = IGnosisSafe(safe).execTransactionFromModule(\n            safe,\n            0,\n            data,\n            IGnosisSafe.Operation.Call\n        );\n        require(success, \"Module Transaction Failed\");\n    }\n\n    /**\n     * @dev This will execute a tx from the safe that will update the safe's ENS in the reverse resolver\n     * @param safe safe address\n     * @param reverseRegistrar The ENS default reverseRegistar\n     * @param _ensString string of pod ens name (i.e.'mypod.pod.xyz')\n     */\n    function setupSafeReverseResolver(\n        address safe,\n        address reverseRegistrar,\n        string memory _ensString\n    ) internal virtual {\n        bytes memory data = abi.encodeWithSignature(\n            \"setName(string)\",\n            _ensString\n        );\n\n        bool success = IGnosisSafe(safe).execTransactionFromModule(\n            reverseRegistrar,\n            0,\n            data,\n            IGnosisSafe.Operation.Call\n        );\n        require(success, \"Module Transaction Failed\");\n    }\n\n    /**\n     * @dev This will be called by the safe at tx time and prevent module disable on pods with admins\n     * @param safe safe address\n     * @param isLocked safe address\n     */\n    function setModuleLock(address safe, bool isLocked) internal {\n        areModulesLocked[safe] = isLocked;\n    }\n\n    /**\n     * @dev This will be called by the safe at execution time time\n     * @param to Destination address of Safe transaction.\n     * @param value Ether value of Safe transaction.\n     * @param data Data payload of Safe transaction.\n     * @param operation Operation type of Safe transaction.\n     * @param safeTxGas Gas that should be used for the Safe transaction.\n     * @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n     * @param gasPrice Gas price that should be used for the payment calculation.\n     * @param gasToken Token address (or 0 if ETH) that is used for the payment.\n     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n     * @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n     * @param msgSender Account executing safe transaction\n     */\n    function checkTransaction(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver,\n        bytes memory signatures,\n        address msgSender\n    ) external view override {\n        address safe = msg.sender;\n        // if safe isn't locked return\n        if (!areModulesLocked[safe]) {\n            return;\n        }\n        if (data.length >= 4) {\n            require(\n                bytes4(data) != ENCODED_SIG_ENABLE_MOD,\n                \"Cannot Enable Modules\"\n            );\n            require(\n                bytes4(data) != ENCODED_SIG_DISABLE_MOD,\n                \"Cannot Disable Modules\"\n            );\n            require(\n                bytes4(data) != ENCODED_SIG_SET_GUARD,\n                \"Cannot Change Guard\"\n            );\n        }\n    }\n\n    function checkAfterExecution(bytes32, bool) external view override {}\n\n    // TODO: move to library\n    // Used in a delegate call to enable module add on setup\n    function enableModule(address module) external {\n        require(module == address(0));\n    }\n\n    /**\n     * Removes the reverse registrar entry and disables module.\n     * Intended as clean up during the safe ejection process.\n     * Note that an already ejected safe cannot clear the reverse registry entry.\n     */\n    function disableModule(\n        address safe,\n        address reverseRegistrar,\n        address previousModule,\n        address module\n    ) external {\n        IGnosisSafe safeContract = IGnosisSafe(safe);\n\n        if (!safeContract.isModuleEnabled(module)) {\n            // Module was already disabled.\n            return;\n        }\n\n        // Note that you cannot clear the reverse registry entry of an already ejected safe.\n        bytes memory nameData = abi.encodeWithSignature(\"setName(string)\", \"\");\n        safeContract.execTransactionFromModule(\n            reverseRegistrar,\n            0,\n            nameData,\n            IGnosisSafe.Operation.Call\n        );\n\n        bytes memory data = abi.encodeWithSignature(\n            \"disableModule(address,address)\",\n            previousModule,\n            module\n        );\n\n        safeContract.execTransactionFromModule(\n            safe,\n            0,\n            data,\n            IGnosisSafe.Operation.Call\n        );\n    }\n\n    function delegateSetup(address _context) external {\n        this.enableModule(_context);\n    }\n}\n"
    },
    "contracts/ens/IPodEnsRegistrar.sol": {
      "content": "pragma solidity ^0.8.7;\n\ninterface IPodEnsRegistrar {\n    function ens() external view returns (address);\n\n    function resolver() external view returns (address);\n\n    function reverseRegistrar() external view returns (address);\n\n    function getRootNode() external view returns (bytes32);\n\n    function registerPod(\n        bytes32 label,\n        address podSafe,\n        address podCreator\n    ) external returns (address);\n\n    function register(bytes32 label, address owner) external;\n\n    function deregister(address safe, bytes32 label) external;\n\n    function setText(\n        bytes32 node,\n        string calldata key,\n        string calldata value\n    ) external;\n\n    function setAddr(bytes32 node, address newAddress) external;\n\n    function addressToNode(address input) external returns (bytes32);\n\n    function getEnsNode(bytes32 label) external view returns (bytes32);\n}\n"
    },
    "lib/ens-contracts/contracts/registry/IReverseRegistrar.sol": {
      "content": "pragma solidity >=0.8.4;\n\ninterface IReverseRegistrar {\n    function setDefaultResolver(address resolver) external;\n\n    function claim(address owner) external returns (bytes32);\n\n    function claimForAddr(\n        address addr,\n        address owner,\n        address resolver\n    ) external returns (bytes32);\n\n    function claimWithResolver(address owner, address resolver)\n        external\n        returns (bytes32);\n\n    function setName(string memory name) external returns (bytes32);\n\n    function setNameForAddr(\n        address addr,\n        address owner,\n        address resolver,\n        string memory name\n    ) external returns (bytes32);\n\n    function node(address addr) external pure returns (bytes32);\n}\n"
    },
    "lib/ens-contracts/contracts/root/Controllable.sol": {
      "content": "pragma solidity ^0.8.4;\n\nimport \"lib/openzeppelin-contracts/contracts/access/Ownable.sol\";\n\ncontract Controllable is Ownable {\n    mapping(address => bool) public controllers;\n\n    event ControllerChanged(address indexed controller, bool enabled);\n\n    modifier onlyController {\n        require(\n            controllers[msg.sender],\n            \"Controllable: Caller is not a controller\"\n        );\n        _;\n    }\n\n    function setController(address controller, bool enabled) public onlyOwner {\n        controllers[controller] = enabled;\n        emit ControllerChanged(controller, enabled);\n    }\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IABIResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"./IABIResolver.sol\";\nimport \"../ResolverBase.sol\";\n\ninterface IABIResolver {\n    event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\n    /**\n     * Returns the ABI associated with an ENS node.\n     * Defined in EIP205.\n     * @param node The ENS node to query\n     * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\n     * @return contentType The content type of the return value\n     * @return data The ABI data\n     */\n    function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IAddressResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the new (multicoin) addr function.\n */\ninterface IAddressResolver {\n    event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);\n\n    function addr(bytes32 node, uint coinType) external view returns(bytes memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IAddrResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the legacy (ETH-only) addr function.\n */\ninterface IAddrResolver {\n    event AddrChanged(bytes32 indexed node, address a);\n\n    /**\n     * Returns the address associated with an ENS node.\n     * @param node The ENS node to query.\n     * @return The associated address.\n     */\n    function addr(bytes32 node) external view returns (address payable);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IContentHashResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IContentHashResolver {\n    event ContenthashChanged(bytes32 indexed node, bytes hash);\n\n    /**\n     * Returns the contenthash associated with an ENS node.\n     * @param node The ENS node to query.\n     * @return The associated contenthash.\n     */\n    function contenthash(bytes32 node) external view returns (bytes memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IDNSRecordResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSRecordResolver {\n    // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\n    event DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record);\n    // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\n    event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\n    // DNSZoneCleared is emitted whenever a given node's zone information is cleared.\n    event DNSZoneCleared(bytes32 indexed node);\n\n    /**\n     * Obtain a DNS record.\n     * @param node the namehash of the node for which to fetch the record\n     * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\n     * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\n     * @return the DNS record in wire format if present, otherwise empty\n     */\n    function dnsRecord(bytes32 node, bytes32 name, uint16 resource) external view returns (bytes memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IDNSZoneResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSZoneResolver {\n    // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\n    event DNSZonehashChanged(bytes32 indexed node, bytes lastzonehash, bytes zonehash);\n\n    /**\n     * zonehash obtains the hash for the zone.\n     * @param node The ENS node to query.\n     * @return The associated contenthash.\n     */\n    function zonehash(bytes32 node) external view returns (bytes memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IInterfaceResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IInterfaceResolver {\n    event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer);\n\n    /**\n     * Returns the address of a contract that implements the specified interface for this name.\n     * If an implementer has not been set for this interfaceID and name, the resolver will query\n     * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\n     * contract implements EIP165 and returns `true` for the specified interfaceID, its address\n     * will be returned.\n     * @param node The ENS node to query.\n     * @param interfaceID The EIP 165 interface ID to check for.\n     * @return The address that implements this interface, or 0 if the interface is unsupported.\n     */\n    function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/INameResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface INameResolver {\n    event NameChanged(bytes32 indexed node, string name);\n\n    /**\n     * Returns the name associated with an ENS node, for reverse records.\n     * Defined in EIP181.\n     * @param node The ENS node to query.\n     * @return The associated name.\n     */\n    function name(bytes32 node) external view returns (string memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IPubkeyResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IPubkeyResolver {\n    event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\n\n    /**\n     * Returns the SECP256k1 public key associated with an ENS node.\n     * Defined in EIP 619.\n     * @param node The ENS node to query\n     * @return x The X coordinate of the curve point for the public key.\n     * @return y The Y coordinate of the curve point for the public key.\n     */\n    function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface ITextResolver {\n    event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);\n\n    /**\n     * Returns the text data associated with an ENS node and key.\n     * @param node The ENS node to query.\n     * @param key The text data key to query.\n     * @return The associated text data.\n     */\n    function text(bytes32 node, string calldata key) external view returns (string memory);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/profiles/IExtendedResolver.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IExtendedResolver {\n    function resolve(bytes memory name, bytes memory data)\n        external\n        view\n        returns (bytes memory, address);\n}\n"
    },
    "lib/ens-contracts/contracts/resolvers/ResolverBase.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol\";\n\nabstract contract ResolverBase is ERC165 {\n    function isAuthorised(bytes32 node) internal virtual view returns(bool);\n\n    modifier authorised(bytes32 node) {\n        require(isAuthorised(node));\n        _;\n    }\n}\n"
    },
    "contracts/interfaces/IGnosisSafe.sol": {
      "content": "pragma solidity ^0.8.7;\n\ninterface IGnosisSafe {\n    enum Operation {\n        Call,\n        DelegateCall\n    }\n\n    /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n    /// @param to Destination address of module transaction.\n    /// @param value Ether value of module transaction.\n    /// @param data Data payload of module transaction.\n    /// @param operation Operation type of module transaction.\n    function execTransactionFromModule(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Operation operation\n    ) external returns (bool success);\n\n    /// @dev Returns array of owners.\n    /// @return Array of Safe owners.\n    function getOwners() external view returns (address[] memory);\n\n    function isOwner(address owner) external view returns (bool);\n\n    function getThreshold() external returns (uint256);\n\n    /// @dev Returns array of modules.\n    /// @param start Start of the page.\n    /// @param pageSize Maximum number of modules that should be returned.\n    /// @return array Array of modules.\n    /// @return next Start of the next page.\n    function getModulesPaginated(address start, uint256 pageSize)\n        external\n        view\n        returns (address[] memory array, address next);\n\n    /// @dev Returns if an module is enabled\n    /// @return True if the module is enabled\n    function isModuleEnabled(address module) external view returns (bool);\n\n    /// @dev Set a guard that checks transactions before execution\n    /// @param guard The address of the guard to be used or the 0 address to disable the guard\n    function setGuard(address guard) external;\n\n    function disableModule(address prevModule, address module) external;\n}\n"
    },
    "contracts/interfaces/IGnosisSafeProxyFactory.sol": {
      "content": "pragma solidity ^0.8.7;\n\ninterface IGnosisSafeProxyFactory {\n    /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n    /// @param singleton Address of singleton contract.\n    /// @param data Payload for message call sent to new proxy contract.\n    function createProxy(address singleton, bytes memory data)\n        external\n        returns (address);\n}\n"
    },
    "lib/safe-contracts/contracts/base/GuardManager.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"../interfaces/IERC165.sol\";\n\ninterface Guard is IERC165 {\n    function checkTransaction(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver,\n        bytes memory signatures,\n        address msgSender\n    ) external;\n\n    function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\nabstract contract BaseGuard is Guard {\n    function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {\n        return\n            interfaceId == type(Guard).interfaceId || // 0xe6d7a83a\n            interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n    }\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract GuardManager is SelfAuthorized {\n    event ChangedGuard(address guard);\n    // keccak256(\"guard_manager.guard.address\")\n    bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n    /// @dev Set a guard that checks transactions before execution\n    /// @param guard The address of the guard to be used or the 0 address to disable the guard\n    function setGuard(address guard) external authorized {\n        if (guard != address(0)) {\n            require(Guard(guard).supportsInterface(type(Guard).interfaceId), \"GS300\");\n        }\n        bytes32 slot = GUARD_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, guard)\n        }\n        emit ChangedGuard(guard);\n    }\n\n    function getGuard() internal view returns (address guard) {\n        bytes32 slot = GUARD_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            guard := sload(slot)\n        }\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/common/Enum.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract Enum {\n    enum Operation {Call, DelegateCall}\n}\n"
    },
    "lib/safe-contracts/contracts/common/SelfAuthorized.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SelfAuthorized {\n    function requireSelfCall() private view {\n        require(msg.sender == address(this), \"GS031\");\n    }\n\n    modifier authorized() {\n        // This is a function call as it minimized the bytecode size\n        requireSelfCall();\n        _;\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/interfaces/IERC165.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
    },
    "lib/safe-contracts/contracts/GnosisSafe.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - <stefan@gnosis.io>\n/// @author Richard Meissner - <richard@gnosis.io>\ncontract GnosisSafe is\n    EtherPaymentFallback,\n    Singleton,\n    ModuleManager,\n    OwnerManager,\n    SignatureDecoder,\n    SecuredTokenTransfer,\n    ISignatureValidatorConstants,\n    FallbackManager,\n    StorageAccessible,\n    GuardManager\n{\n    using GnosisSafeMath for uint256;\n\n    string public constant VERSION = \"1.3.0\";\n\n    // keccak256(\n    //     \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n    // );\n    bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n    // keccak256(\n    //     \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n    // );\n    bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n    event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n    event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n    event SignMsg(bytes32 indexed msgHash);\n    event ExecutionFailure(bytes32 txHash, uint256 payment);\n    event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n    uint256 public nonce;\n    bytes32 private _deprecatedDomainSeparator;\n    // Mapping to keep track of all message hashes that have been approved by ALL REQUIRED owners\n    mapping(bytes32 => uint256) public signedMessages;\n    // Mapping to keep track of all hashes (message or transaction) that have been approved by ANY owners\n    mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n    // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n    constructor() {\n        // By setting the threshold it is not possible to call setup anymore,\n        // so we create a Safe with 0 owners and threshold 1.\n        // This is an unusable Safe, perfect for the singleton\n        threshold = 1;\n    }\n\n    /// @dev Setup function sets initial storage of contract.\n    /// @param _owners List of Safe owners.\n    /// @param _threshold Number of required confirmations for a Safe transaction.\n    /// @param to Contract address for optional delegate call.\n    /// @param data Data payload for optional delegate call.\n    /// @param fallbackHandler Handler for fallback calls to this contract\n    /// @param paymentToken Token that should be used for the payment (0 is ETH)\n    /// @param payment Value that should be paid\n    /// @param paymentReceiver Address that should receive the payment (or 0 if tx.origin)\n    function setup(\n        address[] calldata _owners,\n        uint256 _threshold,\n        address to,\n        bytes calldata data,\n        address fallbackHandler,\n        address paymentToken,\n        uint256 payment,\n        address payable paymentReceiver\n    ) external {\n        // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n        setupOwners(_owners, _threshold);\n        if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n        // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n        setupModules(to, data);\n\n        if (payment > 0) {\n            // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n            // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n            handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n        }\n        emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n    }\n\n    /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n    ///      Note: The fees are always transferred, even if the user transaction fails.\n    /// @param to Destination address of Safe transaction.\n    /// @param value Ether value of Safe transaction.\n    /// @param data Data payload of Safe transaction.\n    /// @param operation Operation type of Safe transaction.\n    /// @param safeTxGas Gas that should be used for the Safe transaction.\n    /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n    /// @param gasPrice Gas price that should be used for the payment calculation.\n    /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n    /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n    /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n    function execTransaction(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver,\n        bytes memory signatures\n    ) public payable virtual returns (bool success) {\n        bytes32 txHash;\n        // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n        {\n            bytes memory txHashData =\n                encodeTransactionData(\n                    // Transaction info\n                    to,\n                    value,\n                    data,\n                    operation,\n                    safeTxGas,\n                    // Payment info\n                    baseGas,\n                    gasPrice,\n                    gasToken,\n                    refundReceiver,\n                    // Signature info\n                    nonce\n                );\n            // Increase nonce and execute transaction.\n            nonce++;\n            txHash = keccak256(txHashData);\n            checkSignatures(txHash, txHashData, signatures);\n        }\n        address guard = getGuard();\n        {\n            if (guard != address(0)) {\n                Guard(guard).checkTransaction(\n                    // Transaction info\n                    to,\n                    value,\n                    data,\n                    operation,\n                    safeTxGas,\n                    // Payment info\n                    baseGas,\n                    gasPrice,\n                    gasToken,\n                    refundReceiver,\n                    // Signature info\n                    signatures,\n                    msg.sender\n                );\n            }\n        }\n        // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n        // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n        require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n        // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n        {\n            uint256 gasUsed = gasleft();\n            // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n            // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n            success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n            gasUsed = gasUsed.sub(gasleft());\n            // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n            // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n            require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n            // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n            uint256 payment = 0;\n            if (gasPrice > 0) {\n                payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n            }\n            if (success) emit ExecutionSuccess(txHash, payment);\n            else emit ExecutionFailure(txHash, payment);\n        }\n        {\n            if (guard != address(0)) {\n                Guard(guard).checkAfterExecution(txHash, success);\n            }\n        }\n    }\n\n    function handlePayment(\n        uint256 gasUsed,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address payable refundReceiver\n    ) private returns (uint256 payment) {\n        // solhint-disable-next-line avoid-tx-origin\n        address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n        if (gasToken == address(0)) {\n            // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n            payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n            require(receiver.send(payment), \"GS011\");\n        } else {\n            payment = gasUsed.add(baseGas).mul(gasPrice);\n            require(transferToken(gasToken, receiver, payment), \"GS012\");\n        }\n    }\n\n    /**\n     * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n     * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n     * @param data That should be signed (this is passed to an external validator contract)\n     * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n     */\n    function checkSignatures(\n        bytes32 dataHash,\n        bytes memory data,\n        bytes memory signatures\n    ) public view {\n        // Load threshold to avoid multiple storage loads\n        uint256 _threshold = threshold;\n        // Check that a threshold is set\n        require(_threshold > 0, \"GS001\");\n        checkNSignatures(dataHash, data, signatures, _threshold);\n    }\n\n    /**\n     * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n     * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n     * @param data That should be signed (this is passed to an external validator contract)\n     * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n     * @param requiredSignatures Amount of required valid signatures.\n     */\n    function checkNSignatures(\n        bytes32 dataHash,\n        bytes memory data,\n        bytes memory signatures,\n        uint256 requiredSignatures\n    ) public view {\n        // Check that the provided signature data is not too short\n        require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n        // There cannot be an owner with address 0.\n        address lastOwner = address(0);\n        address currentOwner;\n        uint8 v;\n        bytes32 r;\n        bytes32 s;\n        uint256 i;\n        for (i = 0; i < requiredSignatures; i++) {\n            (v, r, s) = signatureSplit(signatures, i);\n            if (v == 0) {\n                // If v is 0 then it is a contract signature\n                // When handling contract signatures the address of the contract is encoded into r\n                currentOwner = address(uint160(uint256(r)));\n\n                // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n                // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n                // Here we only check that the pointer is not pointing inside the part that is being processed\n                require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n                // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n                require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n                // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n                uint256 contractSignatureLen;\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    contractSignatureLen := mload(add(add(signatures, s), 0x20))\n                }\n                require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n                // Check signature\n                bytes memory contractSignature;\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n                    contractSignature := add(add(signatures, s), 0x20)\n                }\n                require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n            } else if (v == 1) {\n                // If v is 1 then it is an approved hash\n                // When handling approved hashes the address of the approver is encoded into r\n                currentOwner = address(uint160(uint256(r)));\n                // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n                require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n            } else if (v > 30) {\n                // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n                // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n                currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n            } else {\n                // Default is the ecrecover flow with the provided data hash\n                // Use ecrecover with the messageHash for EOA signatures\n                currentOwner = ecrecover(dataHash, v, r, s);\n            }\n            require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n            lastOwner = currentOwner;\n        }\n    }\n\n    /// @dev Allows to estimate a Safe transaction.\n    ///      This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n    ///      Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n    /// @param to Destination address of Safe transaction.\n    /// @param value Ether value of Safe transaction.\n    /// @param data Data payload of Safe transaction.\n    /// @param operation Operation type of Safe transaction.\n    /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n    /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n    function requiredTxGas(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation\n    ) external returns (uint256) {\n        uint256 startGas = gasleft();\n        // We don't provide an error message here, as we use it to return the estimate\n        require(execute(to, value, data, operation, gasleft()));\n        uint256 requiredGas = startGas - gasleft();\n        // Convert response to string and return via error message\n        revert(string(abi.encodePacked(requiredGas)));\n    }\n\n    /**\n     * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n     * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n     */\n    function approveHash(bytes32 hashToApprove) external {\n        require(owners[msg.sender] != address(0), \"GS030\");\n        approvedHashes[msg.sender][hashToApprove] = 1;\n        emit ApproveHash(hashToApprove, msg.sender);\n    }\n\n    /// @dev Returns the chain id used by this contract.\n    function getChainId() public view returns (uint256) {\n        uint256 id;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            id := chainid()\n        }\n        return id;\n    }\n\n    function domainSeparator() public view returns (bytes32) {\n        return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n    }\n\n    /// @dev Returns the bytes that are hashed to be signed by owners.\n    /// @param to Destination address.\n    /// @param value Ether value.\n    /// @param data Data payload.\n    /// @param operation Operation type.\n    /// @param safeTxGas Gas that should be used for the safe transaction.\n    /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n    /// @param gasPrice Maximum gas price that should be used for this transaction.\n    /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n    /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n    /// @param _nonce Transaction nonce.\n    /// @return Transaction hash bytes.\n    function encodeTransactionData(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address refundReceiver,\n        uint256 _nonce\n    ) public view returns (bytes memory) {\n        bytes32 safeTxHash =\n            keccak256(\n                abi.encode(\n                    SAFE_TX_TYPEHASH,\n                    to,\n                    value,\n                    keccak256(data),\n                    operation,\n                    safeTxGas,\n                    baseGas,\n                    gasPrice,\n                    gasToken,\n                    refundReceiver,\n                    _nonce\n                )\n            );\n        return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n    }\n\n    /// @dev Returns hash to be signed by owners.\n    /// @param to Destination address.\n    /// @param value Ether value.\n    /// @param data Data payload.\n    /// @param operation Operation type.\n    /// @param safeTxGas Fas that should be used for the safe transaction.\n    /// @param baseGas Gas costs for data used to trigger the safe transaction.\n    /// @param gasPrice Maximum gas price that should be used for this transaction.\n    /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n    /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n    /// @param _nonce Transaction nonce.\n    /// @return Transaction hash.\n    function getTransactionHash(\n        address to,\n        uint256 value,\n        bytes calldata data,\n        Enum.Operation operation,\n        uint256 safeTxGas,\n        uint256 baseGas,\n        uint256 gasPrice,\n        address gasToken,\n        address refundReceiver,\n        uint256 _nonce\n    ) public view returns (bytes32) {\n        return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/base/ModuleManager.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - <stefan@gnosis.pm>\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract ModuleManager is SelfAuthorized, Executor {\n    event EnabledModule(address module);\n    event DisabledModule(address module);\n    event ExecutionFromModuleSuccess(address indexed module);\n    event ExecutionFromModuleFailure(address indexed module);\n\n    address internal constant SENTINEL_MODULES = address(0x1);\n\n    mapping(address => address) internal modules;\n\n    function setupModules(address to, bytes memory data) internal {\n        require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n        modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n        if (to != address(0))\n            // Setup has to complete successfully or transaction fails.\n            require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n    }\n\n    /// @dev Allows to add a module to the whitelist.\n    ///      This can only be done via a Safe transaction.\n    /// @notice Enables the module `module` for the Safe.\n    /// @param module Module to be whitelisted.\n    function enableModule(address module) public authorized {\n        // Module address cannot be null or sentinel.\n        require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n        // Module cannot be added twice.\n        require(modules[module] == address(0), \"GS102\");\n        modules[module] = modules[SENTINEL_MODULES];\n        modules[SENTINEL_MODULES] = module;\n        emit EnabledModule(module);\n    }\n\n    /// @dev Allows to remove a module from the whitelist.\n    ///      This can only be done via a Safe transaction.\n    /// @notice Disables the module `module` for the Safe.\n    /// @param prevModule Module that pointed to the module to be removed in the linked list\n    /// @param module Module to be removed.\n    function disableModule(address prevModule, address module) public authorized {\n        // Validate module address and check that it corresponds to module index.\n        require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n        require(modules[prevModule] == module, \"GS103\");\n        modules[prevModule] = modules[module];\n        modules[module] = address(0);\n        emit DisabledModule(module);\n    }\n\n    /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n    /// @param to Destination address of module transaction.\n    /// @param value Ether value of module transaction.\n    /// @param data Data payload of module transaction.\n    /// @param operation Operation type of module transaction.\n    function execTransactionFromModule(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation\n    ) public virtual returns (bool success) {\n        // Only whitelisted modules are allowed.\n        require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n        // Execute transaction without further confirmations.\n        success = execute(to, value, data, operation, gasleft());\n        if (success) emit ExecutionFromModuleSuccess(msg.sender);\n        else emit ExecutionFromModuleFailure(msg.sender);\n    }\n\n    /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n    /// @param to Destination address of module transaction.\n    /// @param value Ether value of module transaction.\n    /// @param data Data payload of module transaction.\n    /// @param operation Operation type of module transaction.\n    function execTransactionFromModuleReturnData(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation\n    ) public returns (bool success, bytes memory returnData) {\n        success = execTransactionFromModule(to, value, data, operation);\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // Load free memory location\n            let ptr := mload(0x40)\n            // We allocate memory for the return data by setting the free memory location to\n            // current free memory location + data size + 32 bytes for data size value\n            mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n            // Store the size\n            mstore(ptr, returndatasize())\n            // Store the data\n            returndatacopy(add(ptr, 0x20), 0, returndatasize())\n            // Point the return data to the correct memory location\n            returnData := ptr\n        }\n    }\n\n    /// @dev Returns if an module is enabled\n    /// @return True if the module is enabled\n    function isModuleEnabled(address module) public view returns (bool) {\n        return SENTINEL_MODULES != module && modules[module] != address(0);\n    }\n\n    /// @dev Returns array of modules.\n    /// @param start Start of the page.\n    /// @param pageSize Maximum number of modules that should be returned.\n    /// @return array Array of modules.\n    /// @return next Start of the next page.\n    function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n        // Init array with max page size\n        array = new address[](pageSize);\n\n        // Populate return array\n        uint256 moduleCount = 0;\n        address currentModule = modules[start];\n        while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n            array[moduleCount] = currentModule;\n            currentModule = modules[currentModule];\n            moduleCount++;\n        }\n        next = currentModule;\n        // Set correct size of returned array\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            mstore(array, moduleCount)\n        }\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/base/OwnerManager.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - <stefan@gnosis.pm>\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract OwnerManager is SelfAuthorized {\n    event AddedOwner(address owner);\n    event RemovedOwner(address owner);\n    event ChangedThreshold(uint256 threshold);\n\n    address internal constant SENTINEL_OWNERS = address(0x1);\n\n    mapping(address => address) internal owners;\n    uint256 internal ownerCount;\n    uint256 internal threshold;\n\n    /// @dev Setup function sets initial storage of contract.\n    /// @param _owners List of Safe owners.\n    /// @param _threshold Number of required confirmations for a Safe transaction.\n    function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n        // Threshold can only be 0 at initialization.\n        // Check ensures that setup function can only be called once.\n        require(threshold == 0, \"GS200\");\n        // Validate that threshold is smaller than number of added owners.\n        require(_threshold <= _owners.length, \"GS201\");\n        // There has to be at least one Safe owner.\n        require(_threshold >= 1, \"GS202\");\n        // Initializing Safe owners.\n        address currentOwner = SENTINEL_OWNERS;\n        for (uint256 i = 0; i < _owners.length; i++) {\n            // Owner address cannot be null.\n            address owner = _owners[i];\n            require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n            // No duplicate owners allowed.\n            require(owners[owner] == address(0), \"GS204\");\n            owners[currentOwner] = owner;\n            currentOwner = owner;\n        }\n        owners[currentOwner] = SENTINEL_OWNERS;\n        ownerCount = _owners.length;\n        threshold = _threshold;\n    }\n\n    /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n    ///      This can only be done via a Safe transaction.\n    /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n    /// @param owner New owner address.\n    /// @param _threshold New threshold.\n    function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n        // Owner address cannot be null, the sentinel or the Safe itself.\n        require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n        // No duplicate owners allowed.\n        require(owners[owner] == address(0), \"GS204\");\n        owners[owner] = owners[SENTINEL_OWNERS];\n        owners[SENTINEL_OWNERS] = owner;\n        ownerCount++;\n        emit AddedOwner(owner);\n        // Change threshold if threshold was changed.\n        if (threshold != _threshold) changeThreshold(_threshold);\n    }\n\n    /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n    ///      This can only be done via a Safe transaction.\n    /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n    /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n    /// @param owner Owner address to be removed.\n    /// @param _threshold New threshold.\n    function removeOwner(\n        address prevOwner,\n        address owner,\n        uint256 _threshold\n    ) public authorized {\n        // Only allow to remove an owner, if threshold can still be reached.\n        require(ownerCount - 1 >= _threshold, \"GS201\");\n        // Validate owner address and check that it corresponds to owner index.\n        require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n        require(owners[prevOwner] == owner, \"GS205\");\n        owners[prevOwner] = owners[owner];\n        owners[owner] = address(0);\n        ownerCount--;\n        emit RemovedOwner(owner);\n        // Change threshold if threshold was changed.\n        if (threshold != _threshold) changeThreshold(_threshold);\n    }\n\n    /// @dev Allows to swap/replace an owner from the Safe with another address.\n    ///      This can only be done via a Safe transaction.\n    /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n    /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n    /// @param oldOwner Owner address to be replaced.\n    /// @param newOwner New owner address.\n    function swapOwner(\n        address prevOwner,\n        address oldOwner,\n        address newOwner\n    ) public authorized {\n        // Owner address cannot be null, the sentinel or the Safe itself.\n        require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n        // No duplicate owners allowed.\n        require(owners[newOwner] == address(0), \"GS204\");\n        // Validate oldOwner address and check that it corresponds to owner index.\n        require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n        require(owners[prevOwner] == oldOwner, \"GS205\");\n        owners[newOwner] = owners[oldOwner];\n        owners[prevOwner] = newOwner;\n        owners[oldOwner] = address(0);\n        emit RemovedOwner(oldOwner);\n        emit AddedOwner(newOwner);\n    }\n\n    /// @dev Allows to update the number of required confirmations by Safe owners.\n    ///      This can only be done via a Safe transaction.\n    /// @notice Changes the threshold of the Safe to `_threshold`.\n    /// @param _threshold New threshold.\n    function changeThreshold(uint256 _threshold) public authorized {\n        // Validate that threshold is smaller than number of owners.\n        require(_threshold <= ownerCount, \"GS201\");\n        // There has to be at least one Safe owner.\n        require(_threshold >= 1, \"GS202\");\n        threshold = _threshold;\n        emit ChangedThreshold(threshold);\n    }\n\n    function getThreshold() public view returns (uint256) {\n        return threshold;\n    }\n\n    function isOwner(address owner) public view returns (bool) {\n        return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n    }\n\n    /// @dev Returns array of owners.\n    /// @return Array of Safe owners.\n    function getOwners() public view returns (address[] memory) {\n        address[] memory array = new address[](ownerCount);\n\n        // populate return array\n        uint256 index = 0;\n        address currentOwner = owners[SENTINEL_OWNERS];\n        while (currentOwner != SENTINEL_OWNERS) {\n            array[index] = currentOwner;\n            currentOwner = owners[currentOwner];\n            index++;\n        }\n        return array;\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/base/FallbackManager.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract FallbackManager is SelfAuthorized {\n    event ChangedFallbackHandler(address handler);\n\n    // keccak256(\"fallback_manager.handler.address\")\n    bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n    function internalSetFallbackHandler(address handler) internal {\n        bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, handler)\n        }\n    }\n\n    /// @dev Allows to add a contract to handle fallback calls.\n    ///      Only fallback calls without value and with data will be forwarded.\n    ///      This can only be done via a Safe transaction.\n    /// @param handler contract to handle fallback calls.\n    function setFallbackHandler(address handler) public authorized {\n        internalSetFallbackHandler(handler);\n        emit ChangedFallbackHandler(handler);\n    }\n\n    // solhint-disable-next-line payable-fallback,no-complex-fallback\n    fallback() external {\n        bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let handler := sload(slot)\n            if iszero(handler) {\n                return(0, 0)\n            }\n            calldatacopy(0, 0, calldatasize())\n            // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n            // Then the address without padding is stored right after the calldata\n            mstore(calldatasize(), shl(96, caller()))\n            // Add 20 bytes for the address appended add the end\n            let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n            returndatacopy(0, 0, returndatasize())\n            if iszero(success) {\n                revert(0, returndatasize())\n            }\n            return(0, returndatasize())\n        }\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/common/EtherPaymentFallback.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract EtherPaymentFallback {\n    event SafeReceived(address indexed sender, uint256 value);\n\n    /// @dev Fallback function accepts Ether transactions.\n    receive() external payable {\n        emit SafeReceived(msg.sender, msg.value);\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/common/Singleton.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n///         This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - <richard@gnosis.io>\ncontract Singleton {\n    // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n    // It should also always be ensured that the address is stored alone (uses a full word)\n    address private singleton;\n}\n"
    },
    "lib/safe-contracts/contracts/common/SignatureDecoder.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SignatureDecoder {\n    /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n    /// @notice Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n    /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n    /// @param signatures concatenated rsv signatures\n    function signatureSplit(bytes memory signatures, uint256 pos)\n        internal\n        pure\n        returns (\n            uint8 v,\n            bytes32 r,\n            bytes32 s\n        )\n    {\n        // The signature format is a compact form of:\n        //   {bytes32 r}{bytes32 s}{uint8 v}\n        // Compact means, uint8 is not padded to 32 bytes.\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let signaturePos := mul(0x41, pos)\n            r := mload(add(signatures, add(signaturePos, 0x20)))\n            s := mload(add(signatures, add(signaturePos, 0x40)))\n            // Here we are loading the last 32 bytes, including 31 bytes\n            // of 's'. There is no 'mload8' to do this.\n            //\n            // 'byte' is not working due to the Solidity parser, so lets\n            // use the second best option, 'and'\n            v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n        }\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/common/SecuredTokenTransfer.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract SecuredTokenTransfer {\n    /// @dev Transfers a token and returns if it was a success\n    /// @param token Token that should be transferred\n    /// @param receiver Receiver to whom the token should be transferred\n    /// @param amount The amount of tokens that should be transferred\n    function transferToken(\n        address token,\n        address receiver,\n        uint256 amount\n    ) internal returns (bool transferred) {\n        // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n        bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            // We write the return value to scratch space.\n            // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n            let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            switch returndatasize()\n                case 0 {\n                    transferred := success\n                }\n                case 0x20 {\n                    transferred := iszero(or(iszero(success), iszero(mload(0))))\n                }\n                default {\n                    transferred := 0\n                }\n        }\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/common/StorageAccessible.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n    /**\n     * @dev Reads `length` bytes of storage in the currents contract\n     * @param offset - the offset in the current contract's storage in words to start reading from\n     * @param length - the number of words (32 bytes) of data to read\n     * @return the bytes that were read.\n     */\n    function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n        bytes memory result = new bytes(length * 32);\n        for (uint256 index = 0; index < length; index++) {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                let word := sload(add(offset, index))\n                mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Performs a delegatecall on a targetContract in the context of self.\n     * Internally reverts execution to avoid side effects (making it static).\n     *\n     * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n     * Specifically, the `returndata` after a call to this method will be:\n     * `success:bool || response.length:uint256 || response:bytes`.\n     *\n     * @param targetContract Address of the contract containing the code to execute.\n     * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n     */\n    function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n            mstore(0x00, success)\n            mstore(0x20, returndatasize())\n            returndatacopy(0x40, 0, returndatasize())\n            revert(0, add(returndatasize(), 0x40))\n        }\n    }\n}\n"
    },
    "lib/safe-contracts/contracts/interfaces/ISignatureValidator.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n    // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n    bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param _data Arbitrary length data signed on the behalf of address(this)\n     * @param _signature Signature byte array associated with _data\n     *\n     * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n     * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n     * MUST allow external calls\n     */\n    function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n"
    },
    "lib/safe-contracts/contracts/external/GnosisSafeMath.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n    /**\n     * @dev Multiplies two numbers, reverts on overflow.\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-solidity/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b);\n\n        return c;\n    }\n\n    /**\n     * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        require(b <= a);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Adds two numbers, reverts on overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a);\n\n        return c;\n    }\n\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"
    },
    "lib/safe-contracts/contracts/base/Executor.sol": {
      "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - <richard@gnosis.pm>\ncontract Executor {\n    function execute(\n        address to,\n        uint256 value,\n        bytes memory data,\n        Enum.Operation operation,\n        uint256 txGas\n    ) internal returns (bool success) {\n        if (operation == Enum.Operation.DelegateCall) {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n            }\n        } else {\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n            }\n        }\n    }\n}\n"
    },
    "contracts/utils/SafeTxHelper.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.7;\nimport \"lib/safe-contracts/contracts/common/Enum.sol\";\nimport \"lib/safe-contracts/contracts/GnosisSafe.sol\";\n\n// used to help generate Txs for onchain approvals\n/* \n    bytes32 txHash = getSafeTxHash(...);\n    safe.approveHash(txHash);\n    executeSafeTxFrom(...);\n*/\n\ncontract SafeTxHelper {\n    function getSafeTxHash(\n        address to,\n        bytes memory data,\n        GnosisSafe safe\n    ) public view returns (bytes32 txHash) {\n        return\n            safe.getTransactionHash(\n                to,\n                0,\n                data,\n                Enum.Operation.Call,\n                // not using the refunder\n                0,\n                0,\n                0,\n                address(0),\n                payable(address(0)),\n                safe.nonce()\n            );\n    }\n\n    function executeSafeTxFrom(\n        address from,\n        bytes memory data,\n        GnosisSafe safe\n    ) public {\n        safe.execTransaction(\n            address(safe),\n            0,\n            data,\n            Enum.Operation.Call,\n            // not using the refunder\n            0,\n            0,\n            0,\n            address(0),\n            payable(address(0)),\n            // (r,s,v) [r - from] [s - unused] [v - 1 flag for onchain approval]\n            abi.encode(from, bytes32(0), bytes1(0x01))\n        );\n    }\n}\n"
    },
    "contracts/ens/PodEnsRegistrar.sol": {
      "content": "pragma solidity 0.8.7;\n\nimport \"lib/ens-contracts/contracts/registry/ENS.sol\";\nimport \"lib/ens-contracts/contracts/registry/ReverseRegistrar.sol\";\nimport \"lib/ens-contracts/contracts/resolvers/Resolver.sol\";\nimport \"../interfaces/IControllerRegistry.sol\";\nimport \"../interfaces/IInviteToken.sol\";\nimport \"lib/openzeppelin-contracts/contracts/access/Ownable.sol\";\n\n/**\n * A registrar that allocates subdomains to the first person to claim them.\n */\ncontract PodEnsRegistrar is Ownable {\n    modifier onlyControllerOrOwner() {\n        require(\n            controllerRegistry.isRegistered(msg.sender) ||\n                owner() == msg.sender,\n            \"sender must be controller/owner\"\n        );\n        _;\n    }\n\n    enum State {\n        onlySafeWithShip, // Only safes with SHIP token\n        onlyShip, // Anyone with SHIP token\n        open, // Anyone can enroll\n        closed // Nobody can enroll, just in case\n    }\n\n    ENS public ens;\n    Resolver public resolver;\n    ReverseRegistrar public reverseRegistrar;\n    IControllerRegistry controllerRegistry;\n    bytes32 rootNode;\n    IInviteToken inviteToken;\n    State public state = State.onlySafeWithShip;\n\n    /**\n     * Constructor.\n     * @param ensAddr The address of the ENS registry.\n     * @param node The node that this registrar administers.\n     */\n    constructor(\n        ENS ensAddr,\n        Resolver resolverAddr,\n        ReverseRegistrar _reverseRegistrar,\n        IControllerRegistry controllerRegistryAddr,\n        bytes32 node,\n        IInviteToken inviteTokenAddr\n    ) {\n        require(address(ensAddr) != address(0), \"Invalid address\");\n        require(address(resolverAddr) != address(0), \"Invalid address\");\n        require(address(_reverseRegistrar) != address(0), \"Invalid address\");\n        require(\n            address(controllerRegistryAddr) != address(0),\n            \"Invalid address\"\n        );\n        require(node != bytes32(0), \"Invalid node\");\n        require(address(inviteTokenAddr) != address(0), \"Invalid address\");\n\n        ens = ensAddr;\n        resolver = resolverAddr;\n        controllerRegistry = controllerRegistryAddr;\n        rootNode = node;\n        reverseRegistrar = _reverseRegistrar;\n        inviteToken = inviteTokenAddr;\n    }\n\n    function registerPod(\n        bytes32 label,\n        address podSafe,\n        address podCreator\n    ) public returns (address) {\n        if (state == State.closed) {\n            revert(\"registrations are closed\");\n        }\n\n        if (state == State.onlySafeWithShip) {\n            // This implicitly prevents safes that were created in this transaction\n            // from registering, as they cannot have a SHIP token balance.\n            require(\n                inviteToken.balanceOf(podSafe) > 0,\n                \"safe must have SHIP token\"\n            );\n            inviteToken.burn(podSafe, 1);\n        }\n        if (state == State.onlyShip) {\n            // Prefer the safe's token over the user's\n            if (inviteToken.balanceOf(podSafe) > 0) {\n                inviteToken.burn(podSafe, 1);\n            } else if (inviteToken.balanceOf(podCreator) > 0) {\n                inviteToken.burn(podCreator, 1);\n            } else {\n                revert(\"sender or safe must have SHIP\");\n            }\n        }\n\n        bytes32 node = keccak256(abi.encodePacked(rootNode, label));\n\n        require(\n            controllerRegistry.isRegistered(msg.sender),\n            \"controller not registered\"\n        );\n\n        require(ens.owner(node) == address(0), \"label is already owned\");\n\n        _register(label, address(this));\n\n        resolver.setAddr(node, podSafe);\n\n        return address(reverseRegistrar);\n    }\n\n    function getRootNode() public view returns (bytes32) {\n        return rootNode;\n    }\n\n    /**\n     * Generates a node hash from the Registrar's root node + the label hash.\n     * @param label - label hash of pod name (i.e., labelhash('mypod'))\n     */\n    function getEnsNode(bytes32 label) public view returns (bytes32) {\n        return keccak256(abi.encodePacked(getRootNode(), label));\n    }\n\n    /**\n     * Returns the reverse registrar node of a given address,\n     * e.g., the node of mypod.addr.reverse.\n     * @param input - an ENS registered address\n     */\n    function addressToNode(address input) public returns (bytes32) {\n        return reverseRegistrar.node(input);\n    }\n\n    /**\n     * Register a name, or change the owner of an existing registration.\n     * @param label The hash of the label to register.\n     */\n    function register(bytes32 label, address owner)\n        public\n        onlyControllerOrOwner\n    {\n        _register(label, owner);\n    }\n\n    /**\n     * Register a name, or change the owner of an existing registration.\n     * @param label The hash of the label to register.\n     */\n    function _register(bytes32 label, address owner) internal {\n        ens.setSubnodeRecord(rootNode, label, owner, address(resolver), 0);\n    }\n\n    /**\n     * @param node - the node hash of an ENS name\n     */\n    function setText(\n        bytes32 node,\n        string memory key,\n        string memory value\n    ) public onlyControllerOrOwner {\n        resolver.setText(node, key, value);\n    }\n\n    function setAddr(bytes32 node, address newAddress)\n        public\n        onlyControllerOrOwner\n    {\n        resolver.setAddr(node, newAddress);\n    }\n\n    function setRestrictionState(uint256 _state) external onlyOwner {\n        state = State(_state);\n    }\n}\n"
    },
    "contracts/interfaces/IInviteToken.sol": {
      "content": "pragma solidity ^0.8.7;\n\nimport \"lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol\";\n\ninterface IInviteToken is IERC20 {\n    function batchMint(address[] calldata accounts, uint256 amount) external;\n\n    function mint(address account, uint256 amount) external;\n\n    function burn(address account, uint256 amount) external;\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 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    /**\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"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
    },
    "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * The default value of {decimals} is 18. To select a different value for\n     * {decimals} you should overload it.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless this function is\n     * overridden;\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n        }\n        _balances[to] += amount;\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        _balances[account] += amount;\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n        }\n        _totalSupply -= amount;\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n}\n"
    },
    "contracts/InviteToken.sol": {
      "content": "pragma solidity ^0.8.7;\n\nimport \"lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol\";\nimport \"lib/openzeppelin-contracts/contracts/access/AccessControl.sol\";\n\ncontract InviteToken is ERC20, AccessControl {\n    bytes32 public constant MINTER_ROLE = keccak256(\"MINTER_ROLE\");\n    bytes32 public constant BURNER_ROLE = keccak256(\"BURNER_ROLE\");\n\n    constructor() ERC20(\"Ship Token\", \"$SHIP\") {\n        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n        _setupRole(MINTER_ROLE, msg.sender);\n        _setupRole(BURNER_ROLE, msg.sender);\n    }\n\n    function decimals() public view override returns (uint8) {\n        return 0;\n    }\n\n    function batchMint(address[] calldata accounts, uint256 amount) public {\n        for (uint256 i = 0; i < accounts.length; i++) {\n            mint(accounts[i], amount);\n        }\n    }\n\n    function mint(address account, uint256 amount) public {\n        require(hasRole(MINTER_ROLE, msg.sender), \"Only minters can mint\");\n        _mint(account, amount);\n    }\n\n    function burn(address account, uint256 amount) public {\n        require(hasRole(BURNER_ROLE, msg.sender), \"Only burners can burn\");\n        _burn(account, amount);\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 1000
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    },
    "libraries": {
      "": {
        "__CACHE_BREAKER__": "0x0000000000000031363537373336363936393036"
      }
    }
  }
}