@@ -24,51 +24,32 @@ contract BridgeValidationHook {
2424 function _verifyBridgeActions (
2525 ProposalAction[] memory proposal
2626 ) internal view {
27- address [] memory targets = new address [](proposal.length );
28- uint256 [] memory values = new uint256 [](proposal.length );
29- bytes [] memory datas = new bytes [](proposal.length );
30-
31- for (uint256 i = 0 ; i < proposal.length ; i++ ) {
32- targets[i] = proposal[i].target;
33- values[i] = proposal[i].value;
34- datas[i] = proposal[i].data;
35- }
36-
37- _verifyBridgeCalls (targets, values, datas);
38- }
39-
40- /// @notice Internal function to verify bridge calls
41- /// @param targets Array of target addresses for each action
42- /// @param values Array of native token values for each action
43- /// @param datas Array of calldata for each action
44- function _verifyBridgeCalls (
45- address [] memory targets ,
46- uint256 [] memory values ,
47- bytes [] memory datas
48- ) internal view {
49- uint256 proposalLength = targets.length ;
27+ uint256 proposalLength = proposal.length ;
5028
5129 for (uint256 i = 0 ; i < proposalLength; i++ ) {
52- bytes4 selector = bytesToBytes4 (datas [i]);
30+ bytes4 selector = bytesToBytes4 (proposal [i].data );
5331
5432 // Check if this action is a bridgeToRecipient call
5533 if (selector == BRIDGE_TO_RECIPIENT_SELECTOR) {
56- address router = targets[i];
57- uint256 actionValue = values[i];
34+ address router = proposal[i].target;
35+ uint256 actionValue = proposal[i].value;
36+
37+ // Validate router is a contract
38+ _validateRouterIsContract (router);
5839
5940 // Extract wormholeChainId from calldata
6041 // Calldata structure:
6142 // 0-3: function selector
6243 // 4-35: address to (32 bytes)
6344 // 36-67: uint256 amount (32 bytes)
6445 // 68-99: uint16 wormholeChainId (32 bytes, right-padded)
65- uint16 wormholeChainId = extractUint16FromCalldata (datas[i]);
66-
67- // Get the actual bridge cost from the router
68- uint256 bridgeCost = xWELLRouter (router).bridgeCost (
69- wormholeChainId
46+ uint16 wormholeChainId = extractUint16FromCalldata (
47+ proposal[i].data
7048 );
7149
50+ // Get the actual bridge cost from the router with validation
51+ uint256 bridgeCost = _getBridgeCost (router, wormholeChainId);
52+
7253 // Validate that action value is between 5x and 10x the bridge cost
7354 uint256 minValue = bridgeCost * MIN_BRIDGE_COST_MULTIPLIER;
7455 uint256 maxValue = bridgeCost * MAX_BRIDGE_COST_MULTIPLIER;
@@ -96,6 +77,31 @@ contract BridgeValidationHook {
9677 }
9778 }
9879
80+ /// @notice Validates that the router address is a contract
81+ /// @param router The router address to validate
82+ function _validateRouterIsContract (address router ) private view {
83+ require (
84+ router.code.length > 0 ,
85+ "BridgeValidationHook: router must be a contract "
86+ );
87+ }
88+
89+ /// @notice Gets bridge cost from router and validates it's non-zero
90+ /// @param router The router contract address
91+ /// @param wormholeChainId The destination chain ID
92+ /// @return bridgeCost The validated bridge cost
93+ function _getBridgeCost (
94+ address router ,
95+ uint16 wormholeChainId
96+ ) private view returns (uint256 bridgeCost ) {
97+ bridgeCost = xWELLRouter (router).bridgeCost (wormholeChainId);
98+
99+ require (
100+ bridgeCost > 0 ,
101+ "BridgeValidationHook: bridge cost must be greater than zero "
102+ );
103+ }
104+
99105 /// @notice Extract uint16 value from calldata at the third parameter position
100106 /// @param input The calldata to extract from
101107 /// @return result The extracted uint16 value
0 commit comments