## ERC-721 & ERC-1155 need "ISCONTRACT" Token transfers in the two main NFT standards behave differently when the receiver is a contract. In that case, the token invokes a callback on the receiver (e.g., [`onERC721Received`](https://eips.ethereum.org/EIPS/eip-721#specification)), and unless a specific value is returned from the callback the transfer is reverted. This is mandated by the specifications. The purpose is to prevent the loss of tokens transferred to contracts that are not able to handle them. This is compatible with account abstraction, but smart contract wallets must implement the callback to declare that they're able to handle the token (e.g., see [Safe](https://github.com/safe-global/safe-smart-account/blob/v1.4.1/contracts/handler/TokenCallbackHandler.sol#L40)). ### Status under EOF It's not possible to use `EXTCODESIZE` or `EXTCODEHASH` in EOFv1, so there's no "native" way to implement this behavior. The currently proposed solution is to work around the limitation by dispatching to an auxiliary Legacy contract that uses `EXTCODESIZE`. For library authors, this creates the problem of having to hardcode addresses of the auxiliary contract on all supported EVM chains. Developers have to ensure the auxiliary contract is present on their local development chain used for testing. ### Possible solutions Enable some form of an `ISCONTRACT` operation in EOFv1, such as: 1. `EXTCODESIZE` with [the same semantics it has on Legacy contracts](https://eips.ethereum.org/EIPS/eip-3540#changes-to-execution-semantics). 2. `EXTCODEHASH` with the same semantics it has on Legacy contracts. 3. `EXTCODESIZE` repurposed as `ISCONTRACT`, returning 1 if the address has any code. 4. `EXTCODEHASH` repurposed as `EXTCODETYPE`, behaving the same as `EXTCODEHASH` except returning a special value for Legacy contracts to prevent code inspection. Because of the possibility of using an auxiliary Legacy contract, none of these options strictly introduces new capabilities to EOF. ## Proxies could be bricked by `DELEGATECALL` limitation In EOFv1, an EOF contract is [not able](https://eips.ethereum.org/EIPS/eip-3540#eof1-contracts-can-only-delegatecall-eof1-contracts) to `DELEGATECALL` into a Legacy contract. The main reason seems to be to fully prevent `SELFDESTRUCT` in the context of an EOF contract, even in its [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780) form. (The concrete issue this would cause is not clear to me.) This creates a new failure mode for EOF upgradeable proxies that assume the upgrade logic is present in the target (aka UUPS proxies). If the proxy target is switched from an EOF contract to a Legacy contract the proxy becomes bricked and unusable, including loss of funds. ### Possible solutions 1. Remove the `DELEGATECALL` limitation so that an EOF contract can delegate to a Legacy contract. 2. Keep the `DELEGATECALL` limitation, but give proxies a way to detect if a contract is EOF to prevent bricking. E.g., `EXTCODEHASH` or `EXTCODETYPE` as described in the previous section.