feat: HypNative routing via HYP_ERC20_COLLATERAL sentinel#4
Open
yorhodes wants to merge 4 commits intohyperlane-xyz:mainfrom
Open
feat: HypNative routing via HYP_ERC20_COLLATERAL sentinel#4yorhodes wants to merge 4 commits intohyperlane-xyz:mainfrom
yorhodes wants to merge 4 commits intohyperlane-xyz:mainfrom
Conversation
Explores whether HypNative (native-ETH) warp routes can be bridged through UniversalRouter without adding a dedicated HYP_NATIVE bridge type, by passing token=address(0) and payer=router into the existing HYP_ERC20_COLLATERAL branch. Tests cover: - no-fee baseline (passes) - mailbox hook fee (exact-output via caller-side amount inflation) - linear warp fee - combined hook + linear fee - origin-chain swap composition (CONTRACT_BALANCE sentinel can't be used with token=address(0); concrete inflated amount + SWEEP is required) Findings are intended as input for deciding between a HypNativeWethWrapper vs. adding a HYP_NATIVE branch to BridgeRouter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds support for HypNative (native-ETH) warp routes on the UniversalRouter BridgeRouter without a new bridge type. The sentinel is `token == address(0)` inside the existing HYP_ERC20_COLLATERAL branch, matching how the rest of the router (Payments.pay/sweep/wrapETH, Dispatcher CONTRACT_BALANCE) already treats address(0) as the native marker. Client logic is identical to the ERC20 collateral flow: * pass amount = CONTRACT_BALANCE * set maxTokenFee as the fee cap * let quoteExactInputBridgeAmount compute the destination-credited amount No caller-side exact-output math — the router drains its native balance and the bridge's own quote resolves fees. WETH sources compose the same way as any ERC20: TRANSFER_FROM + UNWRAP_WETH + BRIDGE_TOKEN(CONTRACT_BALANCE). Changes: * BridgeRouter: on the HYP_ERC20_COLLATERAL branch, when token==0 skip the ERC20 pull/approve and forward the full native amount to transferRemote. * Dispatcher: resolve CONTRACT_BALANCE from address(this).balance when token is ETH (was ERC20.balanceOf unconditionally, which reverts on address(0)). * Tests: replace the exploratory overload file with integrated HypNative cases in bridgeToken.t.sol alongside the HypERC20Collateral tests. Runtime bytecode: 23,759 → 23,801 (+42, still under EIP-170 by 775). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the combined (native hook + native linear warp fee) case for parity with the original PR #4 exploration, and a router-balance gas snapshot to mirror testGas_HypXERC20BridgeRouterBalance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deploys a HypNative on the leaf fork, enrolls bidirectionally between root and leaf, and funds it with native liquidity. Each happy-path HypNative test now calls `_assertHypNativeDelivery` after `router.execute`, which processes the inbound mailbox message on the leaf fork and asserts the recipient's native-balance delta matches the expected bridgeAmount. This closes the last parity gap with HypERC20Collateral's tests, which verify cross-chain delivery on leaf via `leafMailbox.processNextInboundMessage()`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds native-ETH (HypNative) warp route support to the UniversalRouter
BridgeRouterusing the existingHYP_ERC20_COLLATERALbranch withtoken == address(0)as the native sentinel — matching how the rest of the router (Payments.pay/sweep/wrapETH,DispatcherCONTRACT_BALANCE resolution) already treatsaddress(0)as the native marker.Client logic is identical to the ERC20 collateral path:
amount = CONTRACT_BALANCEmaxTokenFeeas a cap (router recomputes actual fee fromquoteTransferRemote)Origin-side composition mirrors the ERC20 pattern too — e.g.
TRANSFER_FROM(WETH) + UNWRAP_WETH + BRIDGE_TOKEN(CONTRACT_BALANCE).Changes
BridgeRouter: on theHYP_ERC20_COLLATERALbranch, whentoken == address(0)skip the ERC20 pull/approve and forward the full nativeamounttotransferRemote(covers bridgeAmount + all fees frommsg.value).Dispatcher: resolveCONTRACT_BALANCEfromaddress(this).balancewhentoken == Constants.ETH(was unconditionalERC20.balanceOf, which reverts onaddress(0)).bridgeToken.t.sol, with bidirectional HypNative deployed on root + leaf and cross-chain delivery verified on leaf.Why the sentinel vs. a new
HYP_NATIVEtypeHypNative.token()literally returnsaddress(0), so the sentinel is semantically accurate.quoteExactInputBridgeAmountalready handles native viaquotes[0].token == token.Test coverage (
bridgeToken.t.sol)Every case uses plain
amount = CONTRACT_BALANCEclient logic — no caller-side fee inflation. Every happy path verifies cross-chain delivery on the leaf fork vialeafMailbox.processNextInboundMessage():test_HypNative_WhenNoFeestest_HypNative_WithHookFeeTestPostDispatchHookfees on required + default hooks; router auto-deducts from balancetest_HypNative_WithLinearWarpFeeLinearFeeat 1% rate;bridgeAmount = amount² / (amount + f(amount)) = 1 ETHexactlytest_HypNative_WithCombinedFeesbridgeAmount, both fee recipients get their cuttest_HypNative_WhenTokenFeeExceedsMaxTokenFeeExceedsMaxrevert when cap is tighttest_HypNative_WethToNative_ThenBridgeTRANSFER_FROM + UNWRAP_WETH + BRIDGE_TOKEN(CONTRACT_BALANCE)testGas_HypNativeBridgetestGas_HypNativeBridgeRouterBalancetestGas_HypXERC20BridgeRouterBalance)Parity with HypERC20Collateral tests
WithLinearWarpFee(+WithHookFee,WithCombinedFees)token=address(0)is the sentinel, no mismatch concepttestGas_HypNativeBridge+testGas_HypNativeBridgeRouterBalanceExtras beyond the Collateral suite: no-fees baseline, combined fees, cap-exceeded revert, WETH→native composition.
Test plan
forge test --mt HypNative -vv(6/6 happy paths + revert passing, cross-chain delivery verified)bridgeToken.t.solsuite unchanged (same 4 pre-existing fork-persistence failures asmain)Notes
The earlier exploratory overload test file (
bridgeTokenHypNativeOverload.t.sol) from commit274375ais superseded by the integrated tests; its coverage is preserved in the new cases.🤖 Generated with Claude Code