From f07e13baa9038c76ebe3dd268cd1f4507a52da68 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Mon, 10 Mar 2025 11:03:18 -0500 Subject: [PATCH 1/4] Added supports interface --- contracts/src/external/HyperdriveTarget0.sol | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/contracts/src/external/HyperdriveTarget0.sol b/contracts/src/external/HyperdriveTarget0.sol index 9cd16cae6..d893c13e5 100644 --- a/contracts/src/external/HyperdriveTarget0.sol +++ b/contracts/src/external/HyperdriveTarget0.sol @@ -532,6 +532,18 @@ 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 (interfaceId == bytes4(0xd9b67a26)) { + return true; + } + return false; + } + /// Helpers /// /// @dev Reverts with the provided bytes. This is useful in getters used From 4febcf1b0efe101c0c457a00dd9d66389da79619 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Mon, 10 Mar 2025 11:07:52 -0500 Subject: [PATCH 2/4] Updated the documentation --- contracts/src/internal/HyperdriveMultiToken.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/src/internal/HyperdriveMultiToken.sol b/contracts/src/internal/HyperdriveMultiToken.sol index ec7990458..91db48e1b 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 From f07b771163bdc561255c7fda68f840447f356237 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Mon, 10 Mar 2025 11:09:18 -0500 Subject: [PATCH 3/4] Prevented returndata bombing --- contracts/src/internal/HyperdriveMultiToken.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/src/internal/HyperdriveMultiToken.sol b/contracts/src/internal/HyperdriveMultiToken.sol index 91db48e1b..d7973ba7a 100644 --- a/contracts/src/internal/HyperdriveMultiToken.sol +++ b/contracts/src/internal/HyperdriveMultiToken.sol @@ -139,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(); } From 74b7c39927fa2072eafa5625482422316c64ed59 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Wed, 12 Mar 2025 14:49:08 -1000 Subject: [PATCH 4/4] Addressed Kurt Barry's review feedback --- contracts/src/external/HyperdriveTarget0.sol | 14 +++++++++----- contracts/src/interfaces/IMultiTokenRead.sol | 11 +++++++++-- test/units/MultiToken.t.sol | 11 +++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/contracts/src/external/HyperdriveTarget0.sol b/contracts/src/external/HyperdriveTarget0.sol index d893c13e5..16fcd746c 100644 --- a/contracts/src/external/HyperdriveTarget0.sol +++ b/contracts/src/external/HyperdriveTarget0.sol @@ -533,15 +533,19 @@ abstract contract HyperdriveTarget0 is } /// @notice Returns whether or not an interface is supported. - /// @param interfaceId The ID of the interface. + /// @param _interfaceId The ID of the interface. /// @return A flag indicating whether or not the interface is supported. function supportsInterface( - bytes4 interfaceId + bytes4 _interfaceId ) external pure returns (bool) { - if (interfaceId == bytes4(0xd9b67a26)) { - return true; + // If the interface ID is the ERC165 or ERC1155 interface, return true. + if ( + _interfaceId == bytes4(0x01ffc9a7) || + _interfaceId == bytes4(0xd9b67a26) + ) { + _revert(abi.encode(true)); } - return false; + _revert(abi.encode(false)); } /// Helpers /// 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/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))); + } }