Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x64350b57bf1e19b8DF145ACa330F3ce6797c30b5
Balance 0 ETH
Nonce 32
Code Size 9264 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

9264 bytes
0x608060405234801561000f575f80fd5b506004361061004a575f3560e01c8063715018a61461004e5780638da5cb5b146100585780639c62ffc314610076578063f2fde38b14610092575b5f80fd5b6100566100ae565b005b6100606100c1565b60405161006d9190610376565b60405180910390f35b610090600480360381019061008b91906103bd565b6100e8565b005b6100ac60048036038101906100a791906103bd565b610157565b005b6100b66101db565b6100bf5f610262565b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f816040516100f69061032a565b6101009190610376565b604051809103905ff080158015610119573d5f803e3d5ffd5b5090507fbe2e7a5b1df2dc0470e142685060e0b93939d7696787e72858acf69fafd02af58160405161014b9190610376565b60405180910390a15050565b61015f6101db565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101cf575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101c69190610376565b60405180910390fd5b6101d881610262565b50565b6101e3610323565b73ffffffffffffffffffffffffffffffffffffffff166102016100c1565b73ffffffffffffffffffffffffffffffffffffffff161461026057610224610323565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016102579190610376565b60405180910390fd5b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f33905090565b612012806103e983390190565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61036082610337565b9050919050565b61037081610356565b82525050565b5f6020820190506103895f830184610367565b92915050565b5f80fd5b61039c81610356565b81146103a6575f80fd5b50565b5f813590506103b781610393565b92915050565b5f602082840312156103d2576103d161038f565b5b5f6103df848285016103a9565b9150509291505056fe608060405234801561000f575f80fd5b506040516120123803806120128339818101604052810190610031919061029f565b325f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100a2575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161009991906102d9565b60405180910390fd5b6100b18161018060201b60201c565b505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161011790610372565b60405180910390fd5b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060146101000a81548160ff02191690831515021790555050610390565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61026e82610245565b9050919050565b61027e81610264565b8114610288575f80fd5b50565b5f8151905061029981610275565b92915050565b5f602082840312156102b4576102b3610241565b5b5f6102c18482850161028b565b91505092915050565b6102d381610264565b82525050565b5f6020820190506102ec5f8301846102ca565b92915050565b5f82825260208201905092915050565b7f6d7573742075736520612076616c6964206174746573746174696f6e206164645f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f61035c6021836102f2565b915061036782610302565b604082019050919050565b5f6020820190508181035f83015261038981610350565b9050919050565b611c758061039d5f395ff3fe608060405234801561000f575f80fd5b50600436106100f7575f3560e01c806375f0bb5211610095578063d861643c11610064578063d861643c1461025c578063dbb0d9091461027a578063f2fde38b14610296578063fb2f199e146102b2576100f8565b806375f0bb52146101e85780638da5cb5b1461020457806393271368146102225780639f6c03f31461023e576100f8565b80633876f07f116100d15780633876f07f146101765780634e959ca314610192578063715018a6146101ae578063728c2972146101b8576100f8565b806301ffc9a7146100fa5780631b6e19801461012a578063257e4e3414610146576100f8565b5b005b610114600480360381019061010f9190610f10565b6102d0565b6040516101219190610f55565b60405180910390f35b610144600480360381019061013f9190610f98565b6103a1565b005b610160600480360381019061015b9190611050565b61044d565b60405161016d91906110a6565b60405180910390f35b610190600480360381019061018b91906110bf565b61046d565b005b6101ac60048036038101906101a791906110ea565b610551565b005b6101b6610691565b005b6101d260048036038101906101cd919061129e565b6106a4565b6040516101df9190611340565b60405180910390f35b61020260048036038101906101fd9190611394565b6106ae565b005b61020c610b69565b60405161021991906114c8565b60405180910390f35b61023c600480360381019061023791906114e1565b610b90565b005b610246610b94565b6040516102539190610f55565b60405180910390f35b610264610ba7565b60405161027191906114c8565b60405180910390f35b610294600480360381019061028f91906110bf565b610bcc565b005b6102b060048036038101906102ab91906110ea565b610c65565b005b6102ba610ce9565b6040516102c79190611340565b60405180910390f35b5f7f945b8148000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061039a57507f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610430576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042790611579565b60405180910390fd5b80600160146101000a81548160ff02191690831515021790555050565b6002602052815f5260405f20602052805f5260405f205f91509150505481565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f390611579565b60405180910390fd5b600160025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f208190555050565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036105bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b690611607565b60405180910390fd5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461064e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064590611579565b60405180910390fd5b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610699610cef565b6106a25f610d76565b565b5f95945050505050565b600160149054906101000a900460ff1615610b5c575f3373ffffffffffffffffffffffffffffffffffffffff1663affed0e06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561070d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107319190611639565b90505f8111610775576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161076c906116d4565b60405180910390fd5b5f3373ffffffffffffffffffffffffffffffffffffffff1663d8d11f788e8e8e8e8e8e8e8e8e60018d6107a8919061171f565b6040518b63ffffffff1660e01b81526004016107cd9a99989796959493929190611880565b602060405180830381865afa1580156107e8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080c9190611935565b90505f60025f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205414610889575050610b5c565b5f3373ffffffffffffffffffffffffffffffffffffffff1663e75235b86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108f79190611639565b905061090d604182610e3790919063ffffffff16565b85511015610950576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610947906119aa565b60405180910390fd5b5f805f80610974604160018761096691906119c8565b610e3790919063ffffffff16565b89511061098a578480610986906119fb565b9550505b5f5b85811015610b205761099e8a82610e77565b8260ff1692508095508196508297505050505f85036109c157835f1c9150610ab2565b600185036109d357835f1c9150610ab1565b601e851115610a61576001876040516020016109ef9190611ab6565b60405160208183030381529060405280519060200120600487610a12919061171f565b86866040515f8152602001604052604051610a309493929190611af6565b6020604051602081039080840390855afa158015610a50573d5f803e3d5ffd5b505050602060405103519150610ab0565b6001878686866040515f8152602001604052604051610a839493929190611af6565b6020604051602081039080840390855afa158015610aa3573d5f803e3d5ffd5b5050506020604051035191505b5b5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b13575050505050505050610b5c565b808060010191505061098c565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b5390611b83565b60405180910390fd5b5050505050505050505050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5050565b600160149054906101000a900460ff1681565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5290611579565b60405180910390fd5b8060038190555050565b610c6d610cef565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610cdd575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401610cd491906114c8565b60405180910390fd5b610ce681610d76565b50565b60035481565b610cf7610ea3565b73ffffffffffffffffffffffffffffffffffffffff16610d15610b69565b73ffffffffffffffffffffffffffffffffffffffff1614610d7457610d38610ea3565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610d6b91906114c8565b60405180910390fd5b565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050815f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f808303610e47575f9050610e71565b5f8284610e549190611ba1565b9050828482610e639190611c0f565b14610e6c575f80fd5b809150505b92915050565b5f805f83604102602081018601519250604081018601519150606081018601515f1a9350509250925092565b5f33905090565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b610eef81610ebb565b8114610ef9575f80fd5b50565b5f81359050610f0a81610ee6565b92915050565b5f60208284031215610f2557610f24610eb3565b5b5f610f3284828501610efc565b91505092915050565b5f8115159050919050565b610f4f81610f3b565b82525050565b5f602082019050610f685f830184610f46565b92915050565b610f7781610f3b565b8114610f81575f80fd5b50565b5f81359050610f9281610f6e565b92915050565b5f60208284031215610fad57610fac610eb3565b5b5f610fba84828501610f84565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610fec82610fc3565b9050919050565b610ffc81610fe2565b8114611006575f80fd5b50565b5f8135905061101781610ff3565b92915050565b5f819050919050565b61102f8161101d565b8114611039575f80fd5b50565b5f8135905061104a81611026565b92915050565b5f806040838503121561106657611065610eb3565b5b5f61107385828601611009565b92505060206110848582860161103c565b9150509250929050565b5f819050919050565b6110a08161108e565b82525050565b5f6020820190506110b95f830184611097565b92915050565b5f602082840312156110d4576110d3610eb3565b5b5f6110e18482850161103c565b91505092915050565b5f602082840312156110ff576110fe610eb3565b5b5f61110c84828501611009565b91505092915050565b61111e8161108e565b8114611128575f80fd5b50565b5f8135905061113981611115565b92915050565b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61118d82611147565b810181811067ffffffffffffffff821117156111ac576111ab611157565b5b80604052505050565b5f6111be610eaa565b90506111ca8282611184565b919050565b5f67ffffffffffffffff8211156111e9576111e8611157565b5b6111f282611147565b9050602081019050919050565b828183375f83830152505050565b5f61121f61121a846111cf565b6111b5565b90508281526020810184848401111561123b5761123a611143565b5b6112468482856111ff565b509392505050565b5f82601f8301126112625761126161113f565b5b813561127284826020860161120d565b91505092915050565b60028110611287575f80fd5b50565b5f813590506112988161127b565b92915050565b5f805f805f60a086880312156112b7576112b6610eb3565b5b5f6112c488828901611009565b95505060206112d58882890161112b565b945050604086013567ffffffffffffffff8111156112f6576112f5610eb7565b5b6113028882890161124e565b93505060606113138882890161128a565b925050608061132488828901611009565b9150509295509295909350565b61133a8161101d565b82525050565b5f6020820190506113535f830184611331565b92915050565b5f61136382610fc3565b9050919050565b61137381611359565b811461137d575f80fd5b50565b5f8135905061138e8161136a565b92915050565b5f805f805f805f805f805f6101608c8e0312156113b4576113b3610eb3565b5b5f6113c18e828f01611009565b9b505060206113d28e828f0161112b565b9a505060408c013567ffffffffffffffff8111156113f3576113f2610eb7565b5b6113ff8e828f0161124e565b99505060606114108e828f0161128a565b98505060806114218e828f0161112b565b97505060a06114328e828f0161112b565b96505060c06114438e828f0161112b565b95505060e06114548e828f01611009565b9450506101006114668e828f01611380565b9350506101208c013567ffffffffffffffff81111561148857611487610eb7565b5b6114948e828f0161124e565b9250506101406114a68e828f01611009565b9150509295989b509295989b9093969950565b6114c281610fe2565b82525050565b5f6020820190506114db5f8301846114b9565b92915050565b5f80604083850312156114f7576114f6610eb3565b5b5f6115048582860161103c565b925050602061151585828601610f84565b9150509250929050565b5f82825260208201905092915050565b7f63616c6c6572206e6f7420617574686f72697a656400000000000000000000005f82015250565b5f61156360158361151f565b915061156e8261152f565b602082019050919050565b5f6020820190508181035f83015261159081611557565b9050919050565b7f6d7573742075736520612076616c6964206174746573746174696f6e206164645f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f6115f160218361151f565b91506115fc82611597565b604082019050919050565b5f6020820190508181035f83015261161e816115e5565b9050919050565b5f8151905061163381611115565b92915050565b5f6020828403121561164e5761164d610eb3565b5b5f61165b84828501611625565b91505092915050565b7f496e76616c6964206e6f6e636520666f72206174746573746174696f6e2067755f8201527f6172640000000000000000000000000000000000000000000000000000000000602082015250565b5f6116be60238361151f565b91506116c982611664565b604082019050919050565b5f6020820190508181035f8301526116eb816116b2565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6117298261108e565b91506117348361108e565b925082820390508181111561174c5761174b6116f2565b5b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f61178482611752565b61178e818561175c565b935061179e81856020860161176c565b6117a781611147565b840191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b600281106117f0576117ef6117b2565b5b50565b5f819050611800826117df565b919050565b5f61180f826117f3565b9050919050565b61181f81611805565b82525050565b5f819050919050565b5f61184861184361183e84610fc3565b611825565b610fc3565b9050919050565b5f6118598261182e565b9050919050565b5f61186a8261184f565b9050919050565b61187a81611860565b82525050565b5f610140820190506118945f83018d6114b9565b6118a1602083018c611097565b81810360408301526118b3818b61177a565b90506118c2606083018a611816565b6118cf6080830189611097565b6118dc60a0830188611097565b6118e960c0830187611097565b6118f660e08301866114b9565b611904610100830185611871565b611912610120830184611097565b9b9a5050505050505050505050565b5f8151905061192f81611026565b92915050565b5f6020828403121561194a57611949610eb3565b5b5f61195784828501611921565b91505092915050565b7f756e6578706563746564207369676e61747572652073747265616d00000000005f82015250565b5f611994601b8361151f565b915061199f82611960565b602082019050919050565b5f6020820190508181035f8301526119c181611988565b9050919050565b5f6119d28261108e565b91506119dd8361108e565b92508282019050808211156119f5576119f46116f2565b5b92915050565b5f611a058261108e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611a3757611a366116f2565b5b600182019050919050565b5f81905092915050565b7f19457468657265756d205369676e6564204d6573736167653a0a3332000000005f82015250565b5f611a80601c83611a42565b9150611a8b82611a4c565b601c82019050919050565b5f819050919050565b611ab0611aab8261101d565b611a96565b82525050565b5f611ac082611a74565b9150611acc8284611a9f565b60208201915081905092915050565b5f60ff82169050919050565b611af081611adb565b82525050565b5f608082019050611b095f830187611331565b611b166020830186611ae7565b611b236040830185611331565b611b306060830184611331565b95945050505050565b7f7472616e73616374696f6e206174746573746174696f6e206d697373696e67005f82015250565b5f611b6d601f8361151f565b9150611b7882611b39565b602082019050919050565b5f6020820190508181035f830152611b9a81611b61565b9050919050565b5f611bab8261108e565b9150611bb68361108e565b9250828202611bc48161108e565b91508282048414831517611bdb57611bda6116f2565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f611c198261108e565b9150611c248361108e565b925082611c3457611c33611be2565b5b82820490509291505056fea26469706673582212203dcb13c4af93bd280b0e232f241c50875cd34d19977550f6d3fd2d9e6029fcb864736f6c634300081a0033a264697066735822122015e1c1ba6389df05a6e07736fb920242a7df446a2dc1cefb1123106e40ec5b8064736f6c634300081a0033

Verified Source Code Partial Match

Compiler: v0.8.26+commit.8a97fa7a EVM: cancun Optimization: No
AttestationGuardFactory.sol 918 lines
// File: contracts/external/Enum.sol


pragma solidity >=0.7.0 <0.9.0;

/**
 * @title Enum - Collection of enums used in Safe Smart Account contracts.
 * @author @safe-global/safe-protocol
 */
library Enum {
    enum Operation {
        Call,
        DelegateCall
    }
}

// File: contracts/external/interfaces/IERC165.sol


pragma solidity >=0.7.0 <0.9.0;

/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by `interfaceId`.
     * See the corresponding EIP section
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: contracts/external/GuardManager.sol


/* solhint-disable one-contract-per-file */
pragma solidity >=0.7.0 <0.9.0;



/// @title Guard Interface
interface Guard is IERC165 {
    /// @notice Checks the transaction details.
    /// @dev The function needs to implement transaction validation logic.
    /// @param to The address to which the transaction is intended.
    /// @param value The value of the transaction in Wei.
    /// @param data The transaction data.
    /// @param operation The type of operation of the transaction.
    /// @param safeTxGas Gas used for the transaction.
    /// @param baseGas The base gas for the transaction.
    /// @param gasPrice The price of gas in Wei for the transaction.
    /// @param gasToken The token used to pay for gas.
    /// @param refundReceiver The address which should receive the refund.
    /// @param signatures The signatures of the transaction.
    /// @param msgSender The address of the message sender.
    function checkTransaction(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address payable refundReceiver,
        bytes memory signatures,
        address msgSender
    ) external;

    /// @notice Checks the module transaction details.
    /// @dev The function needs to implement module transaction validation logic.
    /// @param to The address to which the transaction is intended.
    /// @param value The value of the transaction in Wei.
    /// @param data The transaction data.
    /// @param operation The type of operation of the transaction.
    /// @param module The module involved in the transaction.
    /// @return moduleTxHash The hash of the module transaction.
    function checkModuleTransaction(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation,
        address module
    ) external returns (bytes32 moduleTxHash);

    /// @notice Checks after execution of transaction.
    /// @dev The function needs to implement a check after the execution of the transaction.
    /// @param hash The hash of the transaction.
    /// @param success The status of the transaction execution.
    function checkAfterExecution(bytes32 hash, bool success) external;
}

abstract contract BaseGuard is Guard {
    function supportsInterface(bytes4 interfaceId)
        external
        view
        virtual
        override
        returns (bool)
    {
        return
            interfaceId == type(Guard).interfaceId || // 0x945b8148
            interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7
    }
}
// File: contracts/external/interfaces/IGuardManager.sol


/* solhint-disable one-contract-per-file */
pragma solidity >=0.7.0 <0.9.0;

/**
 * @title IGuardManager - A contract interface managing transaction guards which perform pre and post-checks on Safe transactions.
 * @author @safe-global/safe-protocol
 */
interface IGuardManager {
    event ChangedGuard(address indexed guard);

    /**
     * @dev Set a guard that checks transactions before execution
     *      This can only be done via a Safe transaction.
     *      ⚠️ IMPORTANT: Since a guard has full power to block Safe transaction execution,
     *        a broken guard can cause a denial of service for the Safe. Make sure to carefully
     *        audit the guard code and design recovery mechanisms.
     * @notice Set Transaction Guard `guard` for the Safe. Make sure you trust the guard.
     * @param guard The address of the guard to be used or the 0 address to disable the guard
     */
    function setGuard(address guard) external;
}

// File: contracts/external/interfaces/IModuleManager.sol


pragma solidity >=0.7.0 <0.9.0;



/**
 * @title IModuleManager - An interface of contract managing Safe modules
 * @notice Modules are extensions with unlimited access to a Safe that can be added to a Safe by its owners.
           ⚠️ WARNING: Modules are a security risk since they can execute arbitrary transactions, 
           so only trusted and audited modules should be added to a Safe. A malicious module can
           completely takeover a Safe.
 * @author @safe-global/safe-protocol
 */
interface IModuleManager is IGuardManager {
    event EnabledModule(address indexed module);
    event DisabledModule(address indexed module);
    event ExecutionFromModuleSuccess(address indexed module);
    event ExecutionFromModuleFailure(address indexed module);

    /**
     * @notice Enables the module `module` for the Safe.
     * @dev This can only be done via a Safe transaction.
     * @param module Module to be whitelisted.
     */
    function enableModule(address module) external;

    /**
     * @notice Disables the module `module` for the Safe.
     * @dev This can only be done via a Safe transaction.
     * @param prevModule Previous module in the modules linked list.
     * @param module Module to be removed.
     */
    function disableModule(address prevModule, address module) external;

    /**
     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value` (Native Token)
     * @dev Function is virtual to allow overriding for L2 singleton to emit an event for indexing.
     * @param to Destination address of module transaction.
     * @param value Ether value of module transaction.
     * @param data Data payload of module transaction.
     * @param operation Operation type of module transaction.
     * @return success Boolean flag indicating if the call succeeded.
     */
    function execTransactionFromModule(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation
    ) external returns (bool success);

    /**
     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value` (Native Token) and return data
     * @param to Destination address of module transaction.
     * @param value Ether value of module transaction.
     * @param data Data payload of module transaction.
     * @param operation Operation type of module transaction.
     * @return success Boolean flag indicating if the call succeeded.
     * @return returnData Data returned by the call.
     */
    function execTransactionFromModuleReturnData(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation
    ) external returns (bool success, bytes memory returnData);

    /**
     * @notice Returns if an module is enabled
     * @return True if the module is enabled
     */
    function isModuleEnabled(address module) external view returns (bool);

    /**
     * @notice Returns an array of modules.
     *         If all entries fit into a single page, the next pointer will be 0x1.
     *         If another page is present, next will be the last element of the returned array.
     * @param start Start of the page. Has to be a module or start pointer (0x1 address)
     * @param pageSize Maximum number of modules that should be returned. Has to be > 0
     * @return array Array of modules.
     * @return next Start of the next page.
     */
    function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next);
}

// File: contracts/external/interfaces/IOwnerManager.sol


pragma solidity >=0.7.0 <0.9.0;

/**
 * @title IOwnerManager - Interface for contract which manages Safe owners and a threshold to authorize transactions.
 * @author @safe-global/safe-protocol
 */
interface IOwnerManager {
    event AddedOwner(address indexed owner);
    event RemovedOwner(address indexed owner);
    event ChangedThreshold(uint256 threshold);

    /**
     * @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.
     * @dev This can only be done via a Safe transaction.
     * @param owner New owner address.
     * @param _threshold New threshold.
     */
    function addOwnerWithThreshold(address owner, uint256 _threshold) external;

    /**
     * @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.
     * @dev This can only be done via a Safe transaction.
     * @param prevOwner Owner that pointed to the owner to be removed in the linked list
     * @param owner Owner address to be removed.
     * @param _threshold New threshold.
     */
    function removeOwner(address prevOwner, address owner, uint256 _threshold) external;

    /**
     * @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.
     * @dev This can only be done via a Safe transaction.
     * @param prevOwner Owner that pointed to the owner to be replaced in the linked list
     * @param oldOwner Owner address to be replaced.
     * @param newOwner New owner address.
     */
    function swapOwner(address prevOwner, address oldOwner, address newOwner) external;

    /**
     * @notice Changes the threshold of the Safe to `_threshold`.
     * @dev This can only be done via a Safe transaction.
     * @param _threshold New threshold.
     */
    function changeThreshold(uint256 _threshold) external;

    /**
     * @notice Returns the number of required confirmations for a Safe transaction aka the threshold.
     * @return Threshold number.
     */
    function getThreshold() external view returns (uint256);

    /**
     * @notice Returns if `owner` is an owner of the Safe.
     * @return Boolean if owner is an owner of the Safe.
     */
    function isOwner(address owner) external view returns (bool);

    /**
     * @notice Returns a list of Safe owners.
     * @return Array of Safe owners.
     */
    function getOwners() external view returns (address[] memory);
}

// File: contracts/external/interfaces/IFallbackManager.sol


pragma solidity >=0.7.0 <0.9.0;

/**
 * @title IFallbackManager - A contract interface managing fallback calls made to this contract.
 * @author @safe-global/safe-protocol
 */
interface IFallbackManager {
    event ChangedFallbackHandler(address indexed handler);

    /**
     * @notice Set Fallback Handler to `handler` for the Safe.
     * @dev Only fallback calls without value and with data will be forwarded.
     *      This can only be done via a Safe transaction.
     *      Cannot be set to the Safe itself.
     * @param handler contract to handle fallback calls.
     */
    function setFallbackHandler(address handler) external;
}

// File: contracts/external/interfaces/ISafe.sol


pragma solidity >=0.7.0 <0.9.0;





/**
 * @title ISafe - A multisignature wallet interface with support for confirmations using signed messages based on EIP-712.
 * @author @safe-global/safe-protocol
 */
interface ISafe is IModuleManager, IOwnerManager, IFallbackManager {
    event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);
    event ApproveHash(bytes32 indexed approvedHash, address indexed owner);
    event SignMsg(bytes32 indexed msgHash);
    event ExecutionFailure(bytes32 indexed txHash, uint256 payment);
    event ExecutionSuccess(bytes32 indexed txHash, uint256 payment);

    /**
     * @notice Sets an initial storage of the Safe contract.
     * @dev This method can only be called once.
     *      If a proxy was created without setting up, anyone can call setup and claim the proxy.
     * @param _owners List of Safe owners.
     * @param _threshold Number of required confirmations for a Safe transaction.
     * @param to Contract address for optional delegate call.
     * @param data Data payload for optional delegate call.
     * @param fallbackHandler Handler for fallback calls to this contract
     * @param paymentToken Token that should be used for the payment (0 is ETH)
     * @param payment Value that should be paid
     * @param paymentReceiver Address that should receive the payment (or 0 if tx.origin)
     */
    function setup(
        address[] calldata _owners,
        uint256 _threshold,
        address to,
        bytes calldata data,
        address fallbackHandler,
        address paymentToken,
        uint256 payment,
        address payable paymentReceiver
    ) external;

    /** @notice Executes a `operation` {0: Call, 1: DelegateCall}} transaction to `to` with `value` (Native Currency)
     *          and pays `gasPrice` * `gasLimit` in `gasToken` token to `refundReceiver`.
     * @dev The fees are always transferred, even if the user transaction fails.
     *      This method doesn't perform any sanity check of the transaction, such as:
     *      - if the contract at `to` address has code or not
     *      - if the `gasToken` is a contract or not
     *      It is the responsibility of the caller to perform such checks.
     * @param to Destination address of Safe transaction.
     * @param value Ether value of Safe transaction.
     * @param data Data payload of Safe transaction.
     * @param operation Operation type of Safe transaction.
     * @param safeTxGas Gas that should be used for the Safe transaction.
     * @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)
     * @param gasPrice Gas price that should be used for the payment calculation.
     * @param gasToken Token address (or 0 if ETH) that is used for the payment.
     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).
     * @param signatures Signature data that should be verified.
     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.
     * @return success Boolean indicating transaction's success.
     */
    function execTransaction(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address payable refundReceiver,
        bytes memory signatures
    ) external payable returns (bool success);

    /**
     * @notice Checks whether the signature provided is valid for the provided data and hash. Reverts otherwise.
     * @param dataHash Hash of the data (could be either a message hash or transaction hash)
     * @param signatures Signature data that should be verified.
     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.
     */
    function checkSignatures(bytes32 dataHash, bytes memory signatures) external view;

    /**
     * @notice Checks whether the signature provided is valid for the provided data and hash. Reverts otherwise.
     * @param dataHash Hash of the data (could be either a message hash or transaction hash)
     * @param signatures Signature data that should be verified.
     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.
     * @dev This function makes it compatible with previous versions.
     */
    function checkSignatures(bytes32 dataHash, bytes memory /* IGNORED */, bytes memory signatures) external view;

    /**
     * @notice Checks whether the signature provided is valid for the provided data and hash. Reverts otherwise.
     * @dev Since the EIP-1271 does an external call, be mindful of reentrancy attacks.
     * @param executor Address that executing the transaction.
     *        ⚠️⚠️⚠️ Make sure that the executor address is a legitmate executor.
     *        Incorrectly passed the executor might reduce the threshold by 1 signature. ⚠️⚠️⚠️
     * @param dataHash Hash of the data (could be either a message hash or transaction hash)
     * @param signatures Signature data that should be verified.
     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.
     * @param requiredSignatures Amount of required valid signatures.
     */
    function checkNSignatures(address executor, bytes32 dataHash, bytes memory signatures, uint256 requiredSignatures) external view;

    /**
     * @notice Marks hash `hashToApprove` as approved.
     * @dev This can be used with a pre-approved hash transaction signature.
     *      IMPORTANT: The approved hash stays approved forever. There's no revocation mechanism, so it behaves similarly to ECDSA signatures
     * @param hashToApprove The hash to mark as approved for signatures that are verified by this contract.
     */
    function approveHash(bytes32 hashToApprove) external;

    /**
     * @dev Returns the domain separator for this contract, as defined in the EIP-712 standard.
     * @return bytes32 The domain separator hash.
     */
    function domainSeparator() external view returns (bytes32);

    /**
     * @notice Returns transaction hash to be signed by owners.
     * @param to Destination address.
     * @param value Ether value.
     * @param data Data payload.
     * @param operation Operation type.
     * @param safeTxGas Gas that should be used for the safe transaction.
     * @param baseGas Gas costs for data used to trigger the safe transaction.
     * @param gasPrice Maximum gas price that should be used for this transaction.
     * @param gasToken Token address (or 0 if ETH) that is used for the payment.
     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).
     * @param _nonce Transaction nonce.
     * @return Transaction hash.
     */
    function getTransactionHash(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address refundReceiver,
        uint256 _nonce
    ) external view returns (bytes32);

    /**
     * External getter function for state variables.
     */

    /**
     * @notice Returns the version of the Safe contract.
     * @return Version string.
     */
    // solhint-disable-next-line
    function VERSION() external view returns (string memory);

    /**
     * @notice Returns the nonce of the Safe contract.
     * @return Nonce.
     */
    function nonce() external view returns (uint256);

    /**
     * @notice Returns a uint if the messageHash is signed by the owner.
     * @param messageHash Hash of message that should be checked.
     * @return Number denoting if an owner signed the hash.
     */
    function signedMessages(bytes32 messageHash) external view returns (uint256);

    /**
     * @notice Returns a uint if the messageHash is approved by the owner.
     * @param owner Owner address that should be checked.
     * @param messageHash Hash of message that should be checked.
     * @return Number denoting if an owner approved the hash.
     */
    function approvedHashes(address owner, bytes32 messageHash) external view returns (uint256);
}

// File: contracts/external/SafeMath.sol


pragma solidity >=0.7.0 <0.9.0;

/**
 * @title SafeMath
 * @notice Math operations with safety checks that revert on error (overflow/underflow)
 */
library SafeMath {
    /**
     * @notice Multiplies two numbers, reverts on overflow.
     * @param a First number
     * @param b Second number
     * @return Product of a and b
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
     * @notice Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
     * @param a First number
     * @param b Second number
     * @return Difference of a and b
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
     * @notice Adds two numbers, reverts on overflow.
     * @param a First number
     * @param b Second number
     * @return Sum of a and b
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
     * @notice Returns the largest of two numbers.
     * @param a First number
     * @param b Second number
     * @return Largest of a and b
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }
}
// File: contracts/external/SignatureDecoder.sol


pragma solidity >=0.7.0 <0.9.0;

/**
 * @title SignatureDecoder - Decodes signatures encoded as bytes
 * @author Richard Meissner - @rmeissner
 */
abstract contract SignatureDecoder {
    /**
     * @notice Splits signature bytes into `uint8 v, bytes32 r, bytes32 s`.
     * @dev Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures
     *      The signature format is a compact form of {bytes32 r}{bytes32 s}{uint8 v}
     *      Compact means uint8 is not padded to 32 bytes.
     * @param pos Which signature to read.
     *            A prior bounds check of this parameter should be performed, to avoid out of bounds access.
     * @param signatures Concatenated {r, s, v} signatures.
     * @return v Recovery ID or Safe signature type.
     * @return r Output value r of the signature.
     * @return s Output value s of the signature.
     */
    function signatureSplit(bytes memory signatures, uint256 pos) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
        /* solhint-disable no-inline-assembly */
        /// @solidity memory-safe-assembly
        assembly {
            let signaturePos := mul(0x41, pos)
            r := mload(add(signatures, add(signaturePos, 0x20)))
            s := mload(add(signatures, add(signaturePos, 0x40)))
            v := byte(0, mload(add(signatures, add(signaturePos, 0x60))))
        }
        /* solhint-enable no-inline-assembly */
    }
}
// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: contracts/guard/AttestationGuard.sol


/* solhint-disable one-contract-per-file */
pragma solidity >=0.7.0 <0.9.0;







/**
 * @notice AttestationGuard reverts if the hash that was signed by quorum of owners 
 * has not been attested to by the attestation service. It's presence signifies
 *  operational policy requirements having been met.
 */
contract AttestationGuard is BaseGuard, SignatureDecoder, Ownable {
    using SafeMath for uint256;
    
    address public attestationAuthority;
    bool public attestationOn;

    mapping(address => mapping(bytes32 => uint256)) public attestedHashes;
    // only one attestation policy valid at any one time
    bytes32 public attestationPolicyThumbprint;

    constructor(address _attestationAuthority) Ownable(tx.origin) {
        require(_attestationAuthority != address(0), "must use a valid attestation addr");
        attestationAuthority = _attestationAuthority;
        attestationOn = true;
        // attestationPolicyThumbprint = _attestationPolicyThumbprint;
    }

    // solhint-disable-next-line payable-fallback
    fallback() external {
        // We don't revert on fallback to avoid issues in case of a Safe upgrade
        // E.g. The expected check method might change and then the Safe would be locked.
    }

    function enforceAttestation(bool enforce) external {
        require(msg.sender == attestationAuthority, "caller not authorized");
        attestationOn = enforce;
    }

    function setAttestationAutority(address _attestationAuthority) external {
        require(_attestationAuthority != address(0), "must use a valid attestation addr");
        require(msg.sender == attestationAuthority, "caller not authorized");
        attestationAuthority = _attestationAuthority;
    }

    function setAttestationPolicyThumbprint(
        bytes32 _attestationPolicyThumbprint
    ) external {
        require(msg.sender == attestationAuthority, "caller not authorized");
        attestationPolicyThumbprint = _attestationPolicyThumbprint;
    }

    // called by attestion authority to record a hash that was signed
    // by quroum of oweners, each of which have passed attestation policy
    // requirements (e.g., geolocation, device info, etc.)
    function attestHash(bytes32 hashToApprove) external {
        require(msg.sender == attestationAuthority, "caller not authorized");
        attestedHashes[msg.sender][hashToApprove] = 1;
    }

    // Called by the Safe contract before a transaction is executed.
    // Reverts if the hash that was signed by quorum of owners has not
    // been attested to by the attestation service. It's presence signifies
    // operational policy requirements having been met.
    function checkTransaction(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address payable refundReceiver,
        bytes memory signatures,
        address
    ) external view override {
        if (!attestationOn) {
            return;
        }

        uint256 currentNonce = ISafe(msg.sender).nonce();
        // safe increments nonce by the time the gaurd is called
        require(currentNonce > 0, "Invalid nonce for attestation guard");

        bytes32 txHash = ISafe(msg.sender).getTransactionHash( // Transaction info
            to,
            value,
            data,
            operation,
            safeTxGas,
            // Payment info
            baseGas,
            gasPrice,
            gasToken,
            refundReceiver,
            (currentNonce - 1)
        );

        if (attestedHashes[attestationAuthority][txHash] != 0) {
            return;  // attestion hash found, permit execution to proceed
        }
        // fallback, check if attestation address is one of the owners
        uint256 threshold = ISafe(msg.sender).getThreshold();
        
        require (signatures.length >= threshold.mul(65),  "unexpected signature stream");

        uint256 v;
        bytes32 r;
        bytes32 s;
        address currentOwner;

        // support scenario where attestation service adds its signature to attest
        // to owners passing additional security gates without being one of the signers
        if (signatures.length >= (threshold +1).mul(65)){
            threshold ++;
        }
      
        for (uint256 i = 0; i < threshold; i++) {
            (v, r, s) = signatureSplit(signatures, i);

            if (v == 0) {
                // If v is 0 then it is a contract signature
                // When handling contract signatures the address of the contract is encoded into r
                // sig verification already done by Safe contract
                currentOwner = address(uint160(uint256(r)));

            } else if (v == 1) {
                // If v is 1 then it is an approved hash
                // When handling approved hashes the address of the approver is encoded into r
                currentOwner = address(uint160(uint256(r)));
            } else if (v > 30) {
                // If v > 30 then default va (27,28) has been adjusted for eth_sign flow
                // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover
                currentOwner = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", txHash)), uint8(v - 4), r, s);
            } else {
                // Default is the ecrecover flow with the provided data hash
                // Use ecrecover with the messageHash for EOA signatures
                currentOwner = ecrecover(txHash, uint8(v), r, s);
            }
            
            if (currentOwner == attestationAuthority){
                // attestation authority vouched for this hash
                // can permit execution to proceed
                return;
            }
        }

        // attestation service performs addtional checks on the signners, i.e., geoloc, etc.
        revert("transaction attestation missing");
    }

    function checkAfterExecution(bytes32, bool) external view override {}

    /**
     * @notice Called by the Safe contract before a transaction is executed via a module.
     * @param to Destination address of Safe transaction.
     * @param value Ether value of Safe transaction.
     * @param data Data payload of Safe transaction.
     * @param operation Operation type of Safe transaction.
     * @param module Module executing the transaction.
     */
    function checkModuleTransaction(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation,
        address module
    ) external override returns (bytes32) {}
}

// File: contracts/guard/AttestationGuardFactory.sol


pragma solidity >=0.7.0 <0.9.0;



contract AttestationGuardFactory is Ownable {
    event AttestationGuardCreated(address AttestationGuardAddr);

    constructor() Ownable(msg.sender) {}

    // Function to create a new ChildContract
    function createAttestationGuard(address attestationAuthority) public {
        AttestationGuard guardInstance = new AttestationGuard(
            attestationAuthority
        );
        //transferOwnership(tx.origin);
        emit AttestationGuardCreated(address(guardInstance));
    }
}

Read Contract

owner 0x8da5cb5b → address

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

createAttestationGuard 0x9c62ffc3
address attestationAuthority
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address