Contract Name:
Vyper_contract
Contract Source Code:
File 1 of 1 : recoverooor.vy
{{
"language": "Vyper",
"sources": {
"venv/Lib/site-packages/snekmate/tokens/interfaces/IERC1155.vyi": {
"content": "# pragma version ~=0.4.2\n\"\"\"\n@title EIP-1155 Interface Definition\n@custom:contract-name IERC1155\n@license GNU Affero General Public License v3.0 only\n@author pcaversaccio\n@notice The required interface definition of an ERC-1155\n compliant smart contract as defined in:\n https://eips.ethereum.org/EIPS/eip-1155. Note that\n smart contracts implementing the ERC-1155 standard\n must implement all of the functions in the ERC-1155\n interface. For more details, please refer to:\n https://eips.ethereum.org/EIPS/eip-1155#specification.\n\n Note that Vyper interfaces that implement functions\n with return values that require an upper bound (e.g.\n `Bytes`, `DynArray`, or `String`), the upper bound\n defined in the interface represents the lower bound\n of the implementation:\n https://github.com/vyperlang/vyper/pull/3205.\n\n On how to use interfaces in Vyper, please visit:\n https://vyper.readthedocs.io/en/latest/interfaces.html#interfaces.\n\"\"\"\n\n\n# @dev We import and implement the `IERC165` interface,\n# which is a built-in interface of the Vyper compiler.\nfrom ethereum.ercs import IERC165\nimplements: IERC165\n\n\n# @dev Emitted when `_value` tokens of token type\n# `_id` are transferred from `_from` to `_to` by\n# `_operator`.\nevent TransferSingle:\n _operator: indexed(address)\n _from: indexed(address)\n _to: indexed(address)\n _id: uint256\n _value: uint256\n\n\n# @dev Equivalent to multiple `TransferSingle` events,\n# where `_operator`, `_from`, and `_to` are the same\n# for all transfers.\nevent TransferBatch:\n _operator: indexed(address)\n _from: indexed(address)\n _to: indexed(address)\n _ids: DynArray[uint256, 128]\n _values: DynArray[uint256, 128]\n\n\n# @dev Emitted when `_owner` grants or revokes permission\n# to `_operator` to transfer their tokens, according to\n# `_approved`.\nevent ApprovalForAll:\n _owner: indexed(address)\n _operator: indexed(address)\n _approved: bool\n\n\n# @dev Emitted when the Uniform Resource Identifier (URI)\n# for token type `_id` changes to `_value`, if it is a\n# non-programmatic URI. Note that if an `URI` event was\n# emitted for `_id`, the EIP-1155 standard guarantees that\n# `_value` will equal the value returned by {IERC1155MetadataURI-uri}.\nevent URI:\n _value: String[512]\n _id: indexed(uint256)\n\n\n@external\n@view\ndef supportsInterface(interfaceId: bytes4) -> bool:\n \"\"\"\n @dev Returns `True` if this contract implements the\n interface defined by `interfaceId`.\n @notice For more details on how these identifiers are\n created, please refer to:\n https://eips.ethereum.org/EIPS/eip-165.\n @param interfaceId The 4-byte interface identifier.\n @return bool The verification whether the contract\n implements the interface or not.\n \"\"\"\n ...\n\n\n@external\ndef safeTransferFrom(_from: address, _to: address, _id: uint256, _value: uint256, _data: Bytes[1_024]):\n \"\"\"\n @dev Transfers `_value` tokens of token type `_id` from\n `_from` to `_to`.\n @notice Note that `_to` cannot be the zero address. Also,\n if the caller is not `_from`, it must have been\n approved to spend `_from`'s tokens via `setApprovalForAll`.\n Furthermore, `_from` must have a balance of tokens\n of type `_id` of at least `_value`. Eventually, if\n `_to` refers to a smart contract, it must implement\n {IERC1155Receiver-onERC1155Received} and return the\n acceptance magic value.\n\n WARNING: This function can potentially allow a reentrancy\n attack when transferring tokens to an untrusted contract,\n when invoking {IERC1155Receiver-onERC1155Received} on the\n receiver. Ensure to follow the checks-effects-interactions\n (CEI) pattern and consider employing reentrancy guards when\n interacting with untrusted contracts.\n @param _from The 20-byte address which previously\n owned the token.\n @param _to The 20-byte receiver address.\n @param _id The 32-byte identifier of the token.\n @param _value The 32-byte token amount that is\n being transferred.\n @param _data The maximum 1,024-byte additional data\n with no specified format.\n \"\"\"\n ...\n\n\n@external\ndef safeBatchTransferFrom(\n _from: address, _to: address, _ids: DynArray[uint256, 128], _values: DynArray[uint256, 128], _data: Bytes[1_024]\n):\n \"\"\"\n @dev Batched version of `safeTransferFrom`.\n @notice Note that `_ids` and `_values` must have the\n same length. Also, if `_to` refers to a smart\n contract, it must implement {IERC1155Receiver-onERC1155BatchReceived}\n and return the acceptance magic value.\n\n WARNING: This function can potentially allow a reentrancy\n attack when transferring tokens to an untrusted contract,\n when invoking {IERC1155Receiver-onERC1155BatchReceived} on\n the receiver. Ensure to follow the checks-effects-interactions\n (CEI) pattern and consider employing reentrancy guards when\n interacting with untrusted contracts.\n @param _from The 20-byte address which previously\n owned the token.\n @param _to The 20-byte receiver address.\n @param _ids The 32-byte array of token identifiers. Note\n that the order and length must match the 32-byte\n `_values` array.\n @param _values The 32-byte array of token amounts that are being\n transferred. Note that the order and length must match\n the 32-byte `_ids` array.\n @param _data The maximum 1,024-byte additional data\n with no specified format.\n \"\"\"\n ...\n\n\n@external\n@view\ndef balanceOf(_owner: address, _id: uint256) -> uint256:\n \"\"\"\n @dev Returns the amount of tokens of token type\n `_id` owned by `_owner`.\n @param _owner The 20-byte owner address.\n @param _id The 32-byte identifier of the token.\n @return uint256 The 32-byte token amount owned\n by `_owner`.\n \"\"\"\n ...\n\n\n@external\n@view\ndef balanceOfBatch(_owners: DynArray[address, 128], _ids: DynArray[uint256, 128]) -> DynArray[uint256, 128]:\n \"\"\"\n @dev Batched version of `balanceOf`.\n @notice Note that `_owners` and `_ids` must have the\n same length.\n @param _owners The 20-byte array of owner addresses.\n @param _ids The 32-byte array of token identifiers.\n @return DynArray The 32-byte array of token amounts\n owned by `_owners`.\n \"\"\"\n ...\n\n\n@external\ndef setApprovalForAll(_operator: address, _approved: bool):\n \"\"\"\n @dev Grants or revokes permission to `_operator` to\n transfer the caller's tokens, according to `_approved`.\n @notice Note that `_operator` cannot be the caller.\n @param _operator The 20-byte operator address.\n @param _approved The Boolean variable that sets the\n approval status.\n \"\"\"\n ...\n\n\n@external\n@view\ndef isApprovedForAll(_owner: address, _operator: address) -> bool:\n \"\"\"\n @dev Returns `True` if `_operator` is approved to transfer\n `_owner`'s tokens.\n @notice Note that `_operator` cannot be the caller.\n @param _owner The 20-byte owner address.\n @param _operator The 20-byte operator address.\n @return bool The verification whether `_operator` is approved\n or not.\n \"\"\"\n ...\n",
"sha256sum": "3142f9a1389b3c88970aab8d04d95b7f62acde36292a21b0031a4a592cc65105"
},
"venv/Lib/site-packages/snekmate/utils/multicall.vy": {
"content": "# pragma version ~=0.4.2\n# pragma nonreentrancy off\n\"\"\"\n@title Multicall Functions\n@custom:contract-name multicall\n@license GNU Affero General Public License v3.0 only\n@author pcaversaccio\n@notice These functions can be used to batch together multiple `external`\n function calls into one single `external` function call. Please note\n that this contract is written in the most agnostic way possible and\n users should adjust statically allocatable memory to their specific\n needs before deploying it:\n https://github.com/pcaversaccio/snekmate/discussions/82.\n The implementation is inspired by Matt Solomon's implementation here:\n https://github.com/mds1/multicall/blob/main/src/Multicall3.sol.\n@custom:security You must ensure that any contract that integrates the `CALL`-based\n `multicall` and `multicall_value` functions never holds funds after\n the end of a transaction. Otherwise, any ETH, tokens, or other funds\n held by this contract can be stolen. Also, never approve a contract\n that integrates the `CALL`-based functions `multicall` and `multicall_value`\n to spend your tokens. If you do, anyone can steal your tokens! Eventually,\n please make sure you understand how `msg.sender` works in `CALL` vs\n `DELEGATECALL` to the multicall contract, as well as the risks of\n using `msg.value` in a multicall. To learn more about the latter, see:\n - https://github.com/runtimeverification/verified-smart-contracts/wiki/List-of-Security-Vulnerabilities#payable-multicall,\n - https://samczsun.com/two-rights-might-make-a-wrong.\n\"\"\"\n\n\n# @dev Stores the 1-byte upper bound for the dynamic arrays.\n_DYNARRAY_BOUND: constant(uint8) = max_value(uint8)\n\n\n# @dev Batch struct for ordinary (i.e. `nonpayable`) function calls.\nstruct Batch:\n target: address\n allow_failure: bool\n calldata: Bytes[1_024]\n\n\n# @dev Batch struct for `payable` function calls.\nstruct BatchValue:\n target: address\n allow_failure: bool\n value: uint256\n calldata: Bytes[1_024]\n\n\n# @dev Batch struct for ordinary (i.e. `nonpayable`) function calls\n# using this contract as destination address.\nstruct BatchSelf:\n allow_failure: bool\n calldata: Bytes[1_024]\n\n\n# @dev Result struct for function call results.\nstruct Result:\n success: bool\n return_data: Bytes[max_value(uint8)]\n\n\n@deploy\n@payable\ndef __init__():\n \"\"\"\n @dev To omit the opcodes for checking the `msg.value`\n in the creation-time EVM bytecode, the constructor\n is declared as `payable`.\n \"\"\"\n pass\n\n\n@internal\ndef _multicall(data: DynArray[Batch, _DYNARRAY_BOUND]) -> DynArray[Result, _DYNARRAY_BOUND]:\n \"\"\"\n @dev Aggregates function calls, ensuring that each\n function returns successfully if required.\n Since this function uses `CALL`, the `msg.sender`\n will be the multicall contract itself.\n @notice It is important to note that an external call\n via `raw_call` does not perform an external code\n size check on the target address.\n @param data The array of `Batch` structs.\n @return DynArray The array of `Result` structs.\n \"\"\"\n results: DynArray[Result, _DYNARRAY_BOUND] = []\n success: bool = empty(bool)\n return_data: Bytes[max_value(uint8)] = b\"\"\n for batch: Batch in data:\n if batch.allow_failure:\n success, return_data = raw_call(batch.target, batch.calldata, max_outsize=255, revert_on_failure=False)\n else:\n success = True\n return_data = raw_call(batch.target, batch.calldata, max_outsize=255)\n results.append(Result(success=success, return_data=return_data))\n return results\n\n\n@internal\n@payable\ndef _multicall_value(data: DynArray[BatchValue, _DYNARRAY_BOUND]) -> DynArray[Result, _DYNARRAY_BOUND]:\n \"\"\"\n @dev Aggregates function calls with a `msg.value`,\n ensuring that each function returns successfully\n if required. Since this function uses `CALL`,\n the `msg.sender` will be the multicall contract\n itself.\n @notice It is important to note that an external call\n via `raw_call` does not perform an external code\n size check on the target address.\n @param data The array of `BatchValue` structs.\n @return DynArray The array of `Result` structs.\n \"\"\"\n value_accumulator: uint256 = empty(uint256)\n results: DynArray[Result, _DYNARRAY_BOUND] = []\n success: bool = empty(bool)\n return_data: Bytes[max_value(uint8)] = b\"\"\n for batch: BatchValue in data:\n msg_value: uint256 = batch.value\n # WARNING: If you expect to hold any funds in a contract that integrates\n # this function, you must ensure that the next line uses checked arithmetic!\n # Please read the contract-level security notice carefully. For further\n # insights also, see the following X thread:\n # https://x.com/Guhu95/status/1736983530343981307.\n value_accumulator = unsafe_add(value_accumulator, msg_value)\n if batch.allow_failure:\n success, return_data = raw_call(\n batch.target, batch.calldata, max_outsize=255, value=msg_value, revert_on_failure=False\n )\n else:\n success = True\n return_data = raw_call(batch.target, batch.calldata, max_outsize=255, value=msg_value)\n results.append(Result(success=success, return_data=return_data))\n assert msg.value == value_accumulator, \"multicall: value mismatch\"\n return results\n\n\n@internal\ndef _multicall_self(data: DynArray[BatchSelf, _DYNARRAY_BOUND]) -> DynArray[Result, _DYNARRAY_BOUND]:\n \"\"\"\n @dev Aggregates function calls using `DELEGATECALL`,\n ensuring that each function returns successfully\n if required. Since this function uses `DELEGATECALL`,\n the `msg.sender` remains the same account that\n invoked the function `multicall_self` in the first place.\n @notice Developers can include this function in their own\n contract so that users can submit multiple function\n calls in one transaction. Since the `msg.sender` is\n preserved, it's equivalent to sending multiple transactions\n from an EOA (externally-owned account, i.e. non-contract account).\n\n Furthermore, it is important to note that an external\n call via `raw_call` does not perform an external code\n size check on the target address.\n @param data The array of `BatchSelf` structs.\n @return DynArray The array of `Result` structs.\n \"\"\"\n results: DynArray[Result, _DYNARRAY_BOUND] = []\n success: bool = empty(bool)\n return_data: Bytes[max_value(uint8)] = b\"\"\n for batch: BatchSelf in data:\n if batch.allow_failure:\n success, return_data = raw_call(\n self, batch.calldata, max_outsize=255, is_delegate_call=True, revert_on_failure=False\n )\n else:\n success = True\n return_data = raw_call(self, batch.calldata, max_outsize=255, is_delegate_call=True)\n results.append(Result(success=success, return_data=return_data))\n return results\n\n\n@internal\n@view\ndef _multistaticcall(data: DynArray[Batch, _DYNARRAY_BOUND]) -> DynArray[Result, _DYNARRAY_BOUND]:\n \"\"\"\n @dev Aggregates static function calls, ensuring that each\n function returns successfully if required.\n @notice It is important to note that an external call\n via `raw_call` does not perform an external code\n size check on the target address.\n @param data The array of `Batch` structs.\n @return DynArray The array of `Result` structs.\n \"\"\"\n results: DynArray[Result, _DYNARRAY_BOUND] = []\n success: bool = empty(bool)\n return_data: Bytes[max_value(uint8)] = b\"\"\n for batch: Batch in data:\n if batch.allow_failure:\n success, return_data = raw_call(\n batch.target, batch.calldata, max_outsize=255, is_static_call=True, revert_on_failure=False\n )\n else:\n success = True\n return_data = raw_call(batch.target, batch.calldata, max_outsize=255, is_static_call=True)\n results.append(Result(success=success, return_data=return_data))\n return results\n",
"sha256sum": "b0dce165725de40f288eea09645c5f8f5891dce14b870a2edbf71fa5859ef697"
},
"recoverooor.vy": {
"content": "# pragma version ~=0.4.2\n# pragma nonreentrancy off\n\"\"\"\n@title Multi-Token Recovery Contract\n@custom:contract-name recoverooor\n@license GNU Affero General Public License v3.0 only\n@author pcaversaccio\n@notice These functions support (batch) recovery of both native assets\n and tokens across any standard (e.g., ERC-20, ERC-721, ERC-1155).\n When using EIP-7702 (https://eips.ethereum.org/EIPS/eip-7702),\n you can delegate to this contract and safely invoke and broadcast\n the appropriate recovery function from a trusted `OWNER` account.\n For batch recovery of native assets alongside multiple token transfers\n in a single transaction, use the `recover_multicall` function.\n@custom:security This contract is untested and has not undergone a security audit.\n Use with caution!\n\"\"\"\n\n\n# @dev We import the `IERC20`, `IERC721`, and `IERC1155` interfaces to\n# enable easy recovery of these token types when EIP-7702 delegation is\n# used.\nfrom ethereum.ercs import IERC20\nfrom ethereum.ercs import IERC721\nfrom snekmate.tokens.interfaces import IERC1155\n\n\n# @dev We import the `multicall` module.\n# @notice Please note that the `multicall` module is stateless and therefore\n# does not require the `initializes` keyword for initialisation.\nfrom snekmate.utils import multicall\n\n\n# @dev Stores the upper bound for batch calls.\n_BATCH_SIZE: constant(uint8) = 128\n\n\n# @dev Sets the trusted `OWNER` account.\n# @notice We use an `immutable` variable instead of storage, since writes to storage\n# in the constructor do not persist when using this contract as an implementation.\nOWNER: public(immutable(address))\n\n\n@deploy\ndef __init__(owner_: address):\n \"\"\"\n @dev Transfers the ownership of the contract to a\n (trusted) account `owner_`.\n @param owner_ The 20-byte address of the owner.\n \"\"\"\n OWNER = owner_\n\n\n@external\ndef recover_eth():\n \"\"\"\n @dev Transfers the full ether balance to a (trusted)\n account `OWNER`.\n \"\"\"\n self._check_owner()\n # We force the full ether balance into the `OWNER` address.\n # For the `selfdestruct` behaviour, see: https://eips.ethereum.org/EIPS/eip-6780.\n selfdestruct(OWNER)\n\n\n@external\ndef recover_erc20(tokens: DynArray[IERC20, _BATCH_SIZE]):\n \"\"\"\n @dev Transfers the full ERC-20 balances of the specified\n contract addresses to a (trusted) account `OWNER`.\n @param tokens The 20-byte array of ERC-20 token contract\n addresses that are being transferred.\n \"\"\"\n self._check_owner()\n for token: IERC20 in tokens:\n assert extcall token.transfer(\n OWNER, staticcall token.balanceOf(self), default_return_value=True\n ), \"recoverooor: erc-20 transfer operation did not succeed\"\n\n\n@external\ndef recover_erc721(\n tokens: DynArray[IERC721, _BATCH_SIZE], token_ids: DynArray[DynArray[uint256, _BATCH_SIZE], _BATCH_SIZE]\n):\n \"\"\"\n @dev Transfers all ERC-721 `token_ids` of the specified\n contract addresses to a (trusted) account `OWNER`.\n @param tokens The 20-byte array of ERC-721 token contract\n addresses that are being transferred. Note that the\n length must match the 32-byte `token_ids` array.\n @param token_ids The 32-byte array of ERC-721 `token_ids`\n for each ERC-721 contract that are being transferred.\n Note that the length must match the 20-byte `tokens`\n array.\n \"\"\"\n self._check_owner()\n assert len(tokens) == len(token_ids), \"recoverooor: `tokens` and `token_ids` length mismatch\"\n idx: uint256 = empty(uint256)\n for token: IERC721 in tokens:\n ids: DynArray[uint256, _BATCH_SIZE] = token_ids[idx]\n for id: uint256 in ids:\n extcall token.transferFrom(self, OWNER, id)\n idx = unsafe_add(idx, 1)\n\n\n@external\ndef recover_erc1155(\n tokens: DynArray[IERC1155, _BATCH_SIZE],\n ids: DynArray[DynArray[uint256, _BATCH_SIZE], _BATCH_SIZE],\n amounts: DynArray[DynArray[uint256, _BATCH_SIZE], _BATCH_SIZE],\n):\n \"\"\"\n @dev Transfers all `amounts` for the token type `ids` of the\n specified ERC-1155 contract addresses `tokens` to a (trusted)\n account `OWNER`.\n @param tokens The 20-byte array of ERC-1155 token contract\n addresses that are being transferred. Note that the\n length must match the 32-byte `ids` and `amounts` arrays.\n @param ids The 32-byte array of token identifiers. Note that the\n length must match the 20-byte `tokens` arrays. Furthermore,\n note that for each array entry the order and length must\n match the 32-byte `amounts` array.\n @param amounts The 32-byte array of token amounts that are\n being transferred. Note that the length must match the\n 20-byte `tokens` arrays. Furthermore, note that for each\n array entry the order and length must match the 32-byte\n `ids` array.\n \"\"\"\n self._check_owner()\n assert len(tokens) == len(ids), \"recoverooor: `tokens` and `ids` length mismatch\"\n assert len(tokens) == len(amounts), \"recoverooor: `tokens` and `amounts` length mismatch\"\n idx: uint256 = empty(uint256)\n for token: IERC1155 in tokens:\n assert len(ids[idx]) == len(amounts[idx]), \"recoverooor: `ids` and `amounts` length mismatch\"\n extcall token.safeBatchTransferFrom(self, OWNER, ids[idx], amounts[idx], b\"\")\n idx = unsafe_add(idx, 1)\n\n\n@external\n@payable\ndef recover_multicall(\n data: DynArray[multicall.BatchValue, multicall._DYNARRAY_BOUND]\n) -> DynArray[multicall.Result, multicall._DYNARRAY_BOUND]:\n \"\"\"\n @dev Aggregates function calls with a `msg.value`, ensuring\n that each function returns successfully if required. Since\n this function uses `CALL`, the `msg.sender` will be the\n `recoverooor` contract itself.\n @notice This function is fully customisable and does not enforce\n any transfers to a (trusted) `OWNER` account, although this\n is still the recommended approach.\n @param data The array of `BatchValue` structs.\n @return DynArray The array of `Result` structs.\n \"\"\"\n self._check_owner()\n return multicall._multicall_value(data)\n\n\n@internal\ndef _check_owner():\n \"\"\"\n @dev Throws if the sender is not the owner.\n \"\"\"\n assert msg.sender == OWNER, \"recoverooor: caller is not the owner\"\n",
"sha256sum": "ad0677199c1845d31c9b17654d569faeb79838b55a509fd33d989adde345ef0d"
}
},
"settings": {
"outputSelection": {
"recoverooor.vy": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
},
"search_paths": [
"venv/Lib/site-packages",
"venv",
"."
]
},
"compiler_version": "v0.4.2+commit.c216787f",
"integrity": "af71d809a9eabbed8515c90d13066261f47a89b9fc0264b203ee21d64753cc41"
}}