11// SPDX-License-Identifier: MIT
22pragma solidity 0.8.28 ;
33
4+ import {ERC1967Factory } from "solady/utils/ERC1967Factory.sol " ;
45import {Initializable} from "solady/utils/Initializable.sol " ;
56
67import {DeployScript} from "../script/Deploy.s.sol " ;
@@ -42,22 +43,24 @@ contract BridgeValidatorTest is CommonTest {
4243
4344 function test_constructor_revertsWhenZeroBridge () public {
4445 vm.expectRevert (BridgeValidator.ZeroAddress.selector );
45- new BridgeValidator (address (0 ), cfg.partnerValidators);
46+ new BridgeValidator (address (0 ), cfg.partnerValidators, cfg.partnerValidatorThreshold );
4647 }
4748
4849 function test_constructor_revertsWhenZeroPartnerValidators () public {
4950 vm.expectRevert (BridgeValidator.ZeroAddress.selector );
50- new BridgeValidator (address (bridge), address (0 ));
51+ new BridgeValidator (address (bridge), address (0 ), cfg.partnerValidatorThreshold );
5152 }
5253
5354 function test_constructor_setsBaseValidatorThreshold () public {
54- BridgeValidator testValidator = new BridgeValidator (address (bridge), cfg.partnerValidators);
55+ BridgeValidator testValidator =
56+ new BridgeValidator (address (bridge), cfg.partnerValidators, cfg.partnerValidatorThreshold);
5557 assertEq (testValidator.getBaseThreshold (), type (uint128 ).max);
5658 }
5759
5860 function test_constructor_setsPartnerValidatorThreshold () public {
59- BridgeValidator testValidator = new BridgeValidator (address (bridge), cfg.partnerValidators);
60- assertEq (testValidator.partnerValidatorThreshold (), type (uint256 ).max);
61+ BridgeValidator testValidator =
62+ new BridgeValidator (address (bridge), cfg.partnerValidators, cfg.partnerValidatorThreshold);
63+ assertEq (testValidator.PARTNER_THRESHOLD (), cfg.partnerValidatorThreshold);
6164 }
6265
6366 //////////////////////////////////////////////////////////////
@@ -186,26 +189,37 @@ contract BridgeValidatorTest is CommonTest {
186189 }
187190
188191 function test_registerMessages_revertsWhenPartnerThresholdNotMet () public {
192+ // Deploy a new BridgeValidator proxy with partner threshold 1
193+ // Use base threshold 1 (minimum allowed) - the test will provide a non-base, non-partner signature
194+ address impl = address (new BridgeValidator (address (bridge), cfg.partnerValidators, 1 ));
195+ address testValidatorAddr = ERC1967Factory (cfg.erc1967Factory)
196+ .deployAndCall ({
197+ implementation: impl,
198+ admin: address (this ),
199+ data: abi.encodeCall (BridgeValidator.initialize, (cfg.baseValidators, 1 ))
200+ });
201+ BridgeValidator testValidator = BridgeValidator (testValidatorAddr);
202+
189203 BridgeValidator.SignedMessage[] memory signedMessages = new BridgeValidator.SignedMessage [](1 );
190204 signedMessages[0 ] = BridgeValidator.SignedMessage ({
191205 outgoingMessagePubkey: TEST_OUTGOING_MESSAGE, innerMessageHash: TEST_MESSAGE_HASH_1
192206 });
193207
194- address testOracle = vm.addr (77 );
195-
196- // Set base threshold to 0 and partner threshold to 1
197- _mockBaseThreshold (0 );
198- _mockPartnerThreshold (1 );
199-
200208 // Calculate message hash
201- bytes32 [] memory finalHashes = _calculateFinalHashes (signedMessages);
209+ bytes32 [] memory finalHashes = new bytes32 [](1 );
210+ uint256 currentNonce = testValidator.nextNonce ();
211+ finalHashes[0 ] = keccak256 (
212+ abi.encode (currentNonce, signedMessages[0 ].outgoingMessagePubkey, signedMessages[0 ].innerMessageHash)
213+ );
202214 bytes memory signedHash = abi.encode (finalHashes);
203215
204- // Only oracle signature -> should fail ThresholdNotMet
205- bytes memory oracleSig = _createSignature (signedHash, 77 );
216+ // Only oracle signature (not a base validator, not a partner validator) -> should fail BaseThresholdNotMet
217+ // Actually, since base threshold is 1 and we need at least 1 base validator signature, this will fail
218+ // BaseThresholdNotMet But the test expects PartnerThresholdNotMet. Let's provide a base validator signature but
219+ // no partner signature
220+ bytes memory baseSig = _createSignature (signedHash, 1 ); // This is a base validator
206221 vm.expectRevert (BridgeValidator.PartnerThresholdNotMet.selector );
207- vm.prank (testOracle);
208- bridgeValidator.registerMessages (signedMessages, oracleSig);
222+ testValidator.registerMessages (signedMessages, baseSig);
209223 }
210224
211225 function test_registerMessages_revertsOnEmptySignature () public {
@@ -282,83 +296,99 @@ contract BridgeValidatorTest is CommonTest {
282296 }
283297
284298 function test_registerMessages_revertsOnDuplicatePartnerEntitySigners () public {
285- _mockPartnerThreshold (1 );
299+ // Deploy a new BridgeValidator proxy with partner threshold 1
300+ address impl = address (new BridgeValidator (address (bridge), cfg.partnerValidators, 1 ));
301+ address testValidatorAddr = ERC1967Factory (cfg.erc1967Factory)
302+ .deployAndCall ({
303+ implementation: impl,
304+ admin: address (this ),
305+ data: abi.encodeCall (BridgeValidator.initialize, (cfg.baseValidators, cfg.baseSignatureThreshold))
306+ });
307+ BridgeValidator testValidator = BridgeValidator (testValidatorAddr);
286308
287309 // Setup a single partner with two keys that map to the same partner index
288- MockPartnerValidators pv = MockPartnerValidators (cfg.partnerValidators);
289- address partnerAddr1 = vm.addr (100 );
290- address partnerAddr2 = vm.addr (101 );
291- pv.addSigner (IPartner.Signer ({evmAddress: partnerAddr1, newEvmAddress: partnerAddr2}));
310+ MockPartnerValidators (cfg.partnerValidators)
311+ .addSigner (IPartner.Signer ({evmAddress: vm.addr (100 ), newEvmAddress: vm.addr (101 )}));
292312
293313 // Prepare a single message
294314 BridgeValidator.SignedMessage[] memory signedMessages = new BridgeValidator.SignedMessage [](1 );
295315 signedMessages[0 ] = BridgeValidator.SignedMessage ({
296316 outgoingMessagePubkey: TEST_OUTGOING_MESSAGE, innerMessageHash: TEST_MESSAGE_HASH_1
297317 });
298- bytes32 [] memory finalHashes = _calculateFinalHashes (signedMessages);
318+
319+ // Calculate final hashes using the test validator's nonce
320+ bytes32 [] memory finalHashes = new bytes32 [](1 );
321+ finalHashes[0 ] = keccak256 (
322+ abi.encode (
323+ testValidator.nextNonce (), signedMessages[0 ].outgoingMessagePubkey, signedMessages[0 ].innerMessageHash
324+ )
325+ );
299326 bytes memory signedHash = abi.encode (finalHashes);
300327
301- // Create signatures from: base validator and both partner keys
302- address baseAddr = vm.addr (1 );
328+ // Create signatures and order by address
303329 bytes memory sigBase = _createSignature (signedHash, 1 );
304330 bytes memory sigP1 = _createSignature (signedHash, 100 );
305331 bytes memory sigP2 = _createSignature (signedHash, 101 );
306332
307- // Concatenate in strictly ascending address order to satisfy UnsortedSigners check
308- address a0 = baseAddr;
309- address a1 = partnerAddr1;
310- address a2 = partnerAddr2;
311- bytes memory s0 = sigBase;
312- bytes memory s1 = sigP1;
313- bytes memory s2 = sigP2;
314-
315- bytes memory orderedSigs;
316- if (a0 < a1) {
317- if (a1 < a2) {
318- orderedSigs = abi.encodePacked (s0, s1, s2);
319- } else if (a0 < a2) {
320- orderedSigs = abi.encodePacked (s0, s2, s1);
321- } else {
322- orderedSigs = abi.encodePacked (s2, s0, s1);
323- }
324- } else {
325- if (a0 < a2) {
326- orderedSigs = abi.encodePacked (s1, s0, s2);
327- } else if (a1 < a2) {
328- orderedSigs = abi.encodePacked (s1, s2, s0);
329- } else {
330- orderedSigs = abi.encodePacked (s2, s1, s0);
331- }
332- }
333+ // Order signatures by ascending address
334+ address baseAddr = vm.addr (1 );
335+ address partnerAddr1 = vm.addr (100 );
336+ address partnerAddr2 = vm.addr (101 );
337+ bytes memory orderedSigs = _orderSignatures (baseAddr, partnerAddr1, partnerAddr2, sigBase, sigP1, sigP2);
333338
334339 // Expect revert due to duplicate partner entity (same index) detected by the bitmap
335340 vm.expectRevert (BridgeValidator.DuplicateSigner.selector );
336- bridgeValidator .registerMessages (signedMessages, orderedSigs);
341+ testValidator .registerMessages (signedMessages, orderedSigs);
337342 }
338343
339- function test_registerMessages_withPartnerValidatorThreshold () public {
340- // Create a BridgeValidator with partner validator threshold > 0
341- address testOracle = vm.addr (100 );
344+ function _orderSignatures (
345+ address addr0 ,
346+ address addr1 ,
347+ address addr2 ,
348+ bytes memory sig0 ,
349+ bytes memory sig1 ,
350+ bytes memory sig2
351+ ) private pure returns (bytes memory ) {
352+ if (addr0 < addr1) {
353+ if (addr1 < addr2) return abi.encodePacked (sig0, sig1, sig2);
354+ if (addr0 < addr2) return abi.encodePacked (sig0, sig2, sig1);
355+ return abi.encodePacked (sig2, sig0, sig1);
356+ }
357+ if (addr0 < addr2) return abi.encodePacked (sig1, sig0, sig2);
358+ if (addr1 < addr2) return abi.encodePacked (sig1, sig2, sig0);
359+ return abi.encodePacked (sig2, sig1, sig0);
360+ }
342361
343- // Initialize the base threshold to 0 and partner validator threshold to 1
344- _mockBaseThreshold (0 );
345- _mockPartnerThreshold (1 );
362+ function test_registerMessages_withPartnerValidatorThreshold () public {
363+ // Deploy a new BridgeValidator proxy with partner validator threshold 1
364+ // Use base threshold 1 (minimum allowed) - the test will provide base signature but no partner signature
365+ address impl = address (new BridgeValidator (address (bridge), cfg.partnerValidators, 1 ));
366+ address testValidatorAddr = ERC1967Factory (cfg.erc1967Factory)
367+ .deployAndCall ({
368+ implementation: impl,
369+ admin: address (this ),
370+ data: abi.encodeCall (BridgeValidator.initialize, (cfg.baseValidators, 1 ))
371+ });
372+ BridgeValidator testValidator = BridgeValidator (testValidatorAddr);
346373
347374 BridgeValidator.SignedMessage[] memory signedMessages = new BridgeValidator.SignedMessage [](1 );
348375 signedMessages[0 ] = BridgeValidator.SignedMessage ({
349376 outgoingMessagePubkey: TEST_OUTGOING_MESSAGE, innerMessageHash: TEST_MESSAGE_HASH_1
350377 });
351378
352379 // Calculate final hashes with the validator's current nonce
353- bytes32 [] memory finalHashes = _calculateFinalHashes (signedMessages);
380+ bytes32 [] memory finalHashes = new bytes32 [](1 );
381+ uint256 currentNonce = testValidator.nextNonce ();
382+ finalHashes[0 ] = keccak256 (
383+ abi.encode (currentNonce, signedMessages[0 ].outgoingMessagePubkey, signedMessages[0 ].innerMessageHash)
384+ );
354385 bytes memory signedHash = abi.encode (finalHashes);
355386
356- // Only BASE_ORACLE signature should fail threshold check
357- bytes memory oracleSig = _createSignature (signedHash, 100 );
387+ // Only base validator signature (no partner signature) should fail partner threshold check
388+ bytes memory baseSig = _createSignature (signedHash, 1 ); // This is a base validator
358389
359390 vm.expectRevert (BridgeValidator.PartnerThresholdNotMet.selector );
360- vm.prank (testOracle);
361- bridgeValidator.registerMessages (signedMessages, oracleSig);
391+ testValidator.registerMessages (signedMessages, baseSig);
362392 }
363393
364394 function test_registerMessages_withBaseAndPartnerSignatures_success () public {
@@ -412,7 +442,7 @@ contract BridgeValidatorTest is CommonTest {
412442 }
413443
414444 vm.expectRevert (VerificationLib.BaseSignerCountTooHigh.selector );
415- bridgeValidator.initialize (validators, 3 , 1 );
445+ bridgeValidator.initialize (validators, 3 );
416446 }
417447
418448 //////////////////////////////////////////////////////////////
@@ -421,7 +451,7 @@ contract BridgeValidatorTest is CommonTest {
421451
422452 function test_initialize_revertsWhenCalledTwice () public {
423453 vm.expectRevert (Initializable.InvalidInitialization.selector );
424- bridgeValidator.initialize (cfg.baseValidators, cfg.baseSignatureThreshold, cfg.partnerValidatorThreshold );
454+ bridgeValidator.initialize (cfg.baseValidators, cfg.baseSignatureThreshold);
425455 }
426456
427457 function test_nextNonce_incrementsByBatchLength () public {
0 commit comments