{
    "Function": "cancel",
    "File": "contracts/wallet/QuickAccManager.sol",
    "Parent Contracts": [],
    "High-Level Calls": [
        "SignatureValidator",
        "Identity"
    ],
    "Internal Calls": [
        "keccak256(bytes)",
        "abi.encode()",
        "require(bool,string)",
        "keccak256(bytes)",
        "keccak256(bytes)",
        "abi.encode()",
        "abi.encode()",
        "require(bool,string)",
        "require(bool,string)"
    ],
    "Library Calls": [
        "recoverAddr"
    ],
    "Low-Level Calls": [],
    "Code": "function cancel(Identity identity, QuickAccount calldata acc, uint nonce, bytes calldata sig, Identity.Transaction[] calldata txns) external {\n\t\tbytes32 accHash = keccak256(abi.encode(acc));\n\t\trequire(identity.privileges(address(this)) == accHash, 'WRONG_ACC_OR_NO_PRIV');\n\n\t\tbytes32 hash = keccak256(abi.encode(CANCEL_PREFIX, address(this), block.chainid, accHash, nonce, txns, false));\n\t\taddress signer = SignatureValidator.recoverAddr(hash, sig);\n\t\trequire(signer == acc.one || signer == acc.two, 'INVALID_SIGNATURE');\n\n\t\t// @NOTE: should we allow cancelling even when it's matured? probably not, otherwise there's a minor grief\n\t\t// opportunity: someone wants to cancel post-maturity, and you front them with execScheduled\n\t\tbytes32 hashTx = keccak256(abi.encode(address(this), block.chainid, accHash, nonce, txns));\n\t\trequire(scheduled[hashTx] != 0 && block.timestamp < scheduled[hashTx], 'TOO_LATE');\n\t\tdelete scheduled[hashTx];\n\n\t\temit LogCancelled(hashTx, accHash, signer, block.timestamp);\n\t}"
}