creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/AvoSafe.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17;\n\n/// @title   IAvoSafe\n/// @notice  interface to access _avoWalletImpl on-chain\ninterface IAvoSafe {\n    function _avoWalletImpl() external view returns (address);\n}\n\n/// @title      AvoSafe\n/// @notice     Proxy for AvoWallets as deployed by the AvoFactory.\n///             Basic Proxy with fallback to delegate and address for implementation contract at storage 0x0\n/// @dev        If this contract changes then the deployment addresses for new AvoSafes through factory change too!!\n///             Relayers might want to pass in version as new param then to forward to the correct factory\ncontract AvoSafe {\n    /// @notice address of the Avo wallet logic / implementation contract. IMPORTANT: SAME STORAGE SLOT AS FOR PROXY\n    /// @dev    _avoWalletImpl MUST ALWAYS be the first declared variable here in the proxy and in the logic contract\n    ///         when upgrading, the storage at memory address 0x0 is upgraded (first slot).\n    ///         To reduce deployment costs this variable is internal but can still be retrieved with\n    ///         _avoWalletImpl(), see code and comments in fallback below\n    address internal _avoWalletImpl;\n\n    /// @notice   sets _avoWalletImpl address, fetching it from msg.sender via avoWalletImpl()\n    /// @dev      avoWalletImpl_ is not an input param to not influence the deterministic Create2 address!\n    constructor() {\n        // \"\\x8e\\x7d\\xaf\\x69\" is hardcoded bytes of function selector for avoWalletImpl()\n        (bool success_, bytes memory data_) = msg.sender.call(bytes(\"\\x8e\\x7d\\xaf\\x69\"));\n\n        address avoWalletImpl_;\n        assembly {\n            // cast last 20 bytes of hash to address\n            avoWalletImpl_ := mload(add(data_, 32))\n        }\n\n        if (!success_ || avoWalletImpl_.code.length == 0) {\n            revert();\n        }\n\n        _avoWalletImpl = avoWalletImpl_;\n    }\n\n    /// @notice Delegates the current call to `_avoWalletImpl` unless _avoWalletImpl() is called\n    ///         if _avoWalletImpl() is called then the address for _avoWalletImpl is returned\n    /// @dev    Mostly based on OpenZeppelin Proxy.sol\n    fallback() external payable {\n        assembly {\n            // load address avoWalletImpl_ from storage\n            let avoWalletImpl_ := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n\n            // first 4 bytes of calldata specify which function to call.\n            // if those first 4 bytes == 87e9052a (function selector for _avoWalletImpl()) then we return the _avoWalletImpl address\n            // The value is right padded to 32-bytes with 0s\n            if eq(calldataload(0), 0x87e9052a00000000000000000000000000000000000000000000000000000000) {\n                mstore(0, avoWalletImpl_) // store address avoWalletImpl_ at memory address 0x0\n                return(0, 0x20) // send first 20 bytes of address at memory address 0x0\n            }\n\n            // @dev code below is taken from OpenZeppelin Proxy.sol _delegate function\n\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), avoWalletImpl_, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": false,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}