Description
The Solidity base bridge contract (PolygonZkEVMBridgeV2.sol) supports two leaf types: _LEAF_TYPE_ASSET = 0 for token transfers and _LEAF_TYPE_MESSAGE = 1 for arbitrary cross-chain messages. The bridge provides bridgeMessage() and bridgeMessageWETH() to create message leaves, and claimMessage() to process them with destination contract calls. Critically, claimAsset() and claimMessage() each enforce the expected leaf type, preventing cross-type claims.
The Miden bridge only handles asset transfers. The get_leaf_value procedure reads leafType from memory and includes it in the Keccak-256 leaf hash computation, but never asserts its value. If a CLAIM note is submitted with leafType = 1 (a message leaf from the Solidity side), it would be processed as an asset transfer: the origin address (which for messages is msg.sender, not a token address) would be used to look up a faucet, potentially minting tokens incorrectly.
While the Merkle proof would still be valid since the leaf hash includes the type byte, the semantic mismatch means a message leaf could trigger incorrect token minting.
Impact
A message leaf from another chain could be misinterpreted as an asset transfer on Miden, potentially causing a faucet to mint tokens for a cross-chain message that carries no real value. This is a defense-in-depth gap: the Merkle proof validates the data integrity, but not the semantic interpretation.
Recommended Action
In the claim procedure in bridge_in.masm, assert that the leafType field equals 0 (asset) after loading the leaf data into memory but before verifying the leaf. This prevents message-type leaves from being misinterpreted as asset transfers. The outbound path already hardcodes leafType = 0, so no changes are needed there.
References
Classification
Message bridging (bridgeMessage/claimMessage) is part of the base bridge contract (PolygonZkEVMBridgeV2). However, the specific issue here - the missing leafType validation in Miden's claim path - is Miden-specific since Solidity enforces leaf types via separate claimAsset()/claimMessage() functions.
Description
The Solidity base bridge contract (
PolygonZkEVMBridgeV2.sol) supports two leaf types:_LEAF_TYPE_ASSET = 0for token transfers and_LEAF_TYPE_MESSAGE = 1for arbitrary cross-chain messages. The bridge providesbridgeMessage()andbridgeMessageWETH()to create message leaves, andclaimMessage()to process them with destination contract calls. Critically,claimAsset()andclaimMessage()each enforce the expected leaf type, preventing cross-type claims.The Miden bridge only handles asset transfers. The
get_leaf_valueprocedure readsleafTypefrom memory and includes it in the Keccak-256 leaf hash computation, but never asserts its value. If a CLAIM note is submitted withleafType = 1(a message leaf from the Solidity side), it would be processed as an asset transfer: the origin address (which for messages ismsg.sender, not a token address) would be used to look up a faucet, potentially minting tokens incorrectly.While the Merkle proof would still be valid since the leaf hash includes the type byte, the semantic mismatch means a message leaf could trigger incorrect token minting.
Impact
A message leaf from another chain could be misinterpreted as an asset transfer on Miden, potentially causing a faucet to mint tokens for a cross-chain message that carries no real value. This is a defense-in-depth gap: the Merkle proof validates the data integrity, but not the semantic interpretation.
Recommended Action
In the
claimprocedure inbridge_in.masm, assert that theleafTypefield equals 0 (asset) after loading the leaf data into memory but before verifying the leaf. This prevents message-type leaves from being misinterpreted as asset transfers. The outbound path already hardcodesleafType = 0, so no changes are needed there.References
bridge_in.masmCLAIM.masmPolygonZkEVMBridgeV2.solClassification
Message bridging (
bridgeMessage/claimMessage) is part of the base bridge contract (PolygonZkEVMBridgeV2). However, the specific issue here - the missingleafTypevalidation in Miden's claim path - is Miden-specific since Solidity enforces leaf types via separateclaimAsset()/claimMessage()functions.