Skip to content

a Cross-Chain Nonce Collision Blocks Valid Bridge Claims #25935

@sko94

Description

@sko94

there is an issue because the EVM bridge uses nonce alone as the replay/duplicate-execution key, instead of binding it to the source domain as well. Because one bridge deployment can accept messages from multiple source chains, two different valid transfers from different source chains can legitimately share the same nonce. If chain A’s transfer with nonce N is processed first, chain B’s transfer with nonce N is incorrectly rejected as already processed, even though it is a different signed message.

So there is an impact here as a cross-domain replay-key collision that causes a valid claim on one source chain to block a different valid claim from another source chain, which can lock or deny users’ bridged funds on multi-source deployments.
this should be fixed if need any poc or something else am here to provide it

In bridge/evm/contracts/SuiBridge.sol the contract is declares mapping(uint64 nonce => bool isProcessed) public isTransferProcessed;, then in bridge/evm/contracts/SuiBridge.sol it checks require(!isTransferProcessed[message.nonce], "Message already processed");, and later in bridge/evm/contracts/SuiBridge.sol it marks isTransferProcessed[message.nonce] = true;.
The same pattern exists in bridge/evm/contracts/SuiBridgeV2.sol and bridge/evm/contracts/SuiBridgeV2.sol
Because that key is just message.nonce and does not include the source chain or full message hash, one valid transfer from source chain A can block a different valid transfer from source chain B if they share the same nonce.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions