@@ -32,6 +32,8 @@ import {IMailbox} from "../../contracts/interfaces/IMailbox.sol";
3232import  {ISpecifiesInterchainSecurityModule} from  "../../contracts/interfaces/IInterchainSecurityModule.sol " ;
3333import  {IERC20 } from  "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
3434import  {LinearFee} from  "../../contracts/token/fees/LinearFee.sol " ;
35+ import  {IPostDispatchHook} from  "../../contracts/interfaces/hooks/IPostDispatchHook.sol " ;
36+ import  {StandardHookMetadata} from  "../../contracts/hooks/libs/StandardHookMetadata.sol " ;
3537
3638contract  TokenBridgeCctpV1Test  is  Test  {
3739    using TypeCasts   for  address ;
@@ -670,6 +672,9 @@ contract TokenBridgeCctpV1Test is Test {
670672        assertEq (actualId, id);
671673    }
672674
675+     // needed for hook refunds 
676+     receive () external  payable  {}
677+ 
673678    function testFork_postDispatch  (
674679        bytes32  recipient ,
675680        bytes  calldata  body 
@@ -778,6 +783,53 @@ contract TokenBridgeCctpV1Test is Test {
778783        tbOrigin.postDispatch (bytes ("" ), message);
779784    }
780785
786+     function test_hookType  () public  {
787+         assertEq (tbOrigin.hookType (), uint8 (IPostDispatchHook.HookTypes.CCTP));
788+     }
789+ 
790+     function test_supportsMetadata  () public  {
791+         assertEq (tbOrigin.supportsMetadata (bytes ("" )), true );
792+         assertEq (
793+             tbOrigin.supportsMetadata (
794+                 StandardHookMetadata.format (0 , 100_000 , address (this ))
795+             ),
796+             true 
797+         );
798+     }
799+ 
800+     function test_quoteDispatch  () public  {
801+         assertEq (tbOrigin.quoteDispatch (bytes ("" ), bytes ("" )), 0 );
802+     }
803+ 
804+     function test_postDispatch_refundsExcessValue  (
805+         bytes32  recipient ,
806+         bytes  calldata  body 
807+     ) public  virtual  {
808+         address  refundAddress =  makeAddr ("refundAddress " );
809+         uint256  refundBalanceBefore =  refundAddress.balance;
810+ 
811+         // Create metadata with refund address using standard hook metadata format 
812+         bytes  memory  metadata =  abi.encodePacked (
813+             uint16 (1 ), // variant 
814+             uint256 (0 ), // msgValue 
815+             uint256 (0 ), // gasLimit 
816+             refundAddress // refundAddress 
817+         );
818+ 
819+         uint256  excessValue =  1  ether ;
820+ 
821+         mailboxOrigin.dispatch {value: excessValue}(
822+             destination,
823+             recipient,
824+             body,
825+             metadata,
826+             tbOrigin
827+         );
828+ 
829+         // Verify refund was sent 
830+         assertEq (refundAddress.balance, refundBalanceBefore +  excessValue);
831+     }
832+ 
781833    function test_verify_hookMessage  (bytes  calldata  body ) public  {
782834        TestRecipient recipient =  new  TestRecipient ();
783835        recipient.setInterchainSecurityModule (address (tbDestination));
@@ -964,7 +1016,7 @@ contract TokenBridgeCctpV2Test is TokenBridgeCctpV1Test {
9641016            version,
9651017            address (tokenOrigin).addressToBytes32 (),
9661018            recipient,
967-             amount +  (amount *  maxFee) /  10_000 ,
1019+             amount +  (amount *  maxFee) /  ( 10_000   -  maxFee) ,
9681020            sender.addressToBytes32 (),
9691021            maxFee,
9701022            bytes ("" )
@@ -1401,7 +1453,7 @@ contract TokenBridgeCctpV2Test is TokenBridgeCctpV1Test {
14011453        );
14021454        assertEq (quotes[1 ].token, address (tokenOrigin));
14031455        assertEq (quotes[1 ].amount, amount);
1404-         uint256  fastFee =  (amount *  maxFee) /  10_000 ;
1456+         uint256  fastFee =  (amount *  maxFee) /  ( 10_000   -  maxFee) ;
14051457        assertEq (quotes[2 ].token, address (tokenOrigin));
14061458        assertEq (quotes[2 ].amount, fastFee);
14071459    }
0 commit comments