File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ ---
2+ ' @hyperlane-xyz/core ' : minor
3+ ---
4+
5+ Added a sender check in CctpBase._ postDispatch to prevent misuse when called via transferRemote.
Original file line number Diff line number Diff line change @@ -66,6 +66,7 @@ abstract contract TokenBridgeCctpBase is
6666 error InvalidMintAmount ();
6767 error InvalidMintRecipient ();
6868 error InvalidMessageId ();
69+ error InvalidPostDispatchSender ();
6970
7071 uint256 private constant _SCALE = 1 ;
7172
@@ -345,6 +346,13 @@ abstract contract TokenBridgeCctpBase is
345346 bytes calldata metadata ,
346347 bytes calldata message
347348 ) internal override {
349+ // Prevent backrunning transferRemote with postDispatch for the same message.
350+ // transferRemote dispatches with sender == address(this). If an attacker
351+ // backruns it with postDispatch, a second Circle "hook" message is created
352+ // that can set isVerified[messageId] = true on the destination without
353+ // executing the Circle mint, permanently stranding the user's burned funds.
354+ if (message.senderAddress () == address (this ))
355+ revert InvalidPostDispatchSender ();
348356 bytes32 id = message.id ();
349357 if (! _isLatestDispatched (id)) revert MessageNotDispatched ();
350358
Original file line number Diff line number Diff line change @@ -792,6 +792,23 @@ contract TokenBridgeCctpV1Test is Test {
792792 tbOrigin.postDispatch (bytes ("" ), message);
793793 }
794794
795+ function test_postDispatch_revertsWhen_senderIsThis (
796+ bytes32 recipient ,
797+ bytes calldata body
798+ ) public {
799+ bytes memory message = Message.formatMessage (
800+ 3 ,
801+ 0 ,
802+ origin,
803+ address (tbOrigin).addressToBytes32 (),
804+ destination,
805+ recipient,
806+ body
807+ );
808+ vm.expectRevert (TokenBridgeCctpBase.InvalidPostDispatchSender.selector );
809+ tbOrigin.postDispatch (bytes ("" ), message);
810+ }
811+
795812 function test_hookType () public {
796813 assertEq (tbOrigin.hookType (), uint8 (IPostDispatchHook.HookTypes.CCTP));
797814 }
You can’t perform that action at this time.
0 commit comments