diff --git a/contracts/src/external/HyperdriveTarget0.sol b/contracts/src/external/HyperdriveTarget0.sol index 9cd16cae6..16fcd746c 100644 --- a/contracts/src/external/HyperdriveTarget0.sol +++ b/contracts/src/external/HyperdriveTarget0.sol @@ -532,6 +532,22 @@ abstract contract HyperdriveTarget0 is _revert(abi.encode(_nonces[account])); } + /// @notice Returns whether or not an interface is supported. + /// @param _interfaceId The ID of the interface. + /// @return A flag indicating whether or not the interface is supported. + function supportsInterface( + bytes4 _interfaceId + ) external pure returns (bool) { + // If the interface ID is the ERC165 or ERC1155 interface, return true. + if ( + _interfaceId == bytes4(0x01ffc9a7) || + _interfaceId == bytes4(0xd9b67a26) + ) { + _revert(abi.encode(true)); + } + _revert(abi.encode(false)); + } + /// Helpers /// /// @dev Reverts with the provided bytes. This is useful in getters used diff --git a/contracts/src/interfaces/IMultiTokenRead.sol b/contracts/src/interfaces/IMultiTokenRead.sol index ca1ddc678..ecb329570 100644 --- a/contracts/src/interfaces/IMultiTokenRead.sol +++ b/contracts/src/interfaces/IMultiTokenRead.sol @@ -61,7 +61,14 @@ interface IMultiTokenRead { ) external view returns (uint256[] memory); /// @notice Gets the permit nonce for an account. - /// @param owner The owner of the tokens. + /// @param _owner The owner of the tokens. /// @return The permit nonce of the owner. - function nonces(address owner) external view returns (uint256); + function nonces(address _owner) external view returns (uint256); + + /// @notice Returns whether or not an interface is supported. + /// @param _interfaceId The ID of the interface. + /// @return A flag indicating whether or not the interface is supported. + function supportsInterface( + bytes4 _interfaceId + ) external pure returns (bool); } diff --git a/contracts/src/internal/HyperdriveMultiToken.sol b/contracts/src/internal/HyperdriveMultiToken.sol index ec7990458..d7973ba7a 100644 --- a/contracts/src/internal/HyperdriveMultiToken.sol +++ b/contracts/src/internal/HyperdriveMultiToken.sol @@ -11,9 +11,7 @@ import { HyperdriveBase } from "./HyperdriveBase.sol"; /// @notice Implements the MultiToken accounting that Hyperdrive uses to track /// user's positions. MultiToken maintains a set of balances and /// approvals for a list of sub-tokens specified by an asset ID. This -/// token is mostly ERC1155 compliant; however, we remove on transfer -/// callbacks and safe transfer because of the risk of external calls to -/// untrusted code. +/// token is ERC1155 compliant. /// @dev Our architecture maintains ERC20 compatibility by allowing users to /// access their balances and approvals through ERC20 forwarding contracts /// deployed by the registered forwarder factory. To ensure that only the @@ -141,8 +139,6 @@ abstract contract HyperdriveMultiToken is IHyperdriveEvents, HyperdriveBase { if (response != IERC1155Receiver.onERC1155Received.selector) { revert IHyperdrive.ERC1155InvalidReceiver(); } - } catch Error(string memory reason) { - revert(reason); } catch { revert IHyperdrive.ERC1155InvalidReceiver(); } diff --git a/test/units/MultiToken.t.sol b/test/units/MultiToken.t.sol index 16d000c37..7e1d2e419 100644 --- a/test/units/MultiToken.t.sol +++ b/test/units/MultiToken.t.sol @@ -598,4 +598,15 @@ contract MultiTokenTest is HyperdriveTest { // Verify balance update assertEq(hyperdrive.balanceOf(1, address(receiver)), 100 ether); } + + function testSupportsInterface() public view { + // Ensure that Hyperdrive supports the ERC165 interface. + assertTrue(hyperdrive.supportsInterface(bytes4(0x01ffc9a7))); + + // Ensure that Hyperdrive supports the ERC1155 interface. + assertTrue(hyperdrive.supportsInterface(bytes4(0xd9b67a26))); + + // Ensure that Hyperdrive doesn't support a random interface. + assertFalse(hyperdrive.supportsInterface(bytes4(0xdeadbeef))); + } }