Skip to content

Commit

Permalink
test(coverage): slashing release (#383)
Browse files Browse the repository at this point in the history
* test: improve signature checker coverage

* test: improve operator state retriever coverage

* test: improve service manager base coverage

* test: improve service manager base coverage

* chore: forge fmt

* test: improve service manager base coverage

* fix: ci

* test: improve service manager base coverage

* chore: forge fmt
  • Loading branch information
0xClandestine authored Feb 5, 2025
1 parent 9e4afb8 commit 59e22ce
Show file tree
Hide file tree
Showing 4 changed files with 533 additions and 8 deletions.
8 changes: 0 additions & 8 deletions .github/workflows/foundry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,6 @@ jobs:
run-coverage:
name: Coverage
runs-on: ubuntu-latest
# Only run coverage checks on dev, testnet-holesky, and mainnet branches, or PRs targeting these branches
if: |
github.ref == 'refs/heads/dev' ||
github.ref == 'refs/heads/testnet-holesky' ||
github.ref == 'refs/heads/mainnet' ||
github.base_ref == 'dev' ||
github.base_ref == 'testnet-holesky' ||
github.base_ref == 'mainnet'
strategy:
fail-fast: true
steps:
Expand Down
71 changes: 71 additions & 0 deletions test/unit/BLSSignatureCheckerUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -582,4 +582,75 @@ contract BLSSignatureCheckerUnitTests is BLSMockAVSDeployer {
msgHash, quorumNumbers, referenceBlockNumber, nonSignerStakesAndSignature
);
}

function test_trySignatureAndApkVerification_success() public {
uint256 numNonSigners = 0;
uint256 quorumBitmap = 1;
(
uint32 referenceBlockNumber,
BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature
) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(
1, numNonSigners, quorumBitmap
);

(bool pairingSuccessful, bool signatureIsValid) = blsSignatureChecker
.trySignatureAndApkVerification(
msgHash,
nonSignerStakesAndSignature.quorumApks[0],
nonSignerStakesAndSignature.apkG2,
nonSignerStakesAndSignature.sigma
);

assertTrue(pairingSuccessful, "Pairing should be successful");
assertTrue(signatureIsValid, "Signature should be valid");
}

function test_trySignatureAndApkVerification_invalidSignature() public {
uint256 numNonSigners = 0;
uint256 quorumBitmap = 1;
(
uint32 referenceBlockNumber,
BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature
) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(
1, numNonSigners, quorumBitmap
);

// Modify sigma to make it invalid
nonSignerStakesAndSignature.sigma.X++;

cheats.expectRevert();
blsSignatureChecker.trySignatureAndApkVerification(
msgHash,
nonSignerStakesAndSignature.quorumApks[0],
nonSignerStakesAndSignature.apkG2,
nonSignerStakesAndSignature.sigma
);
}

function test_trySignatureAndApkVerification_invalidPairing() public {
uint256 numNonSigners = 0;
uint256 quorumBitmap = 1;
(
uint32 referenceBlockNumber,
BLSSignatureChecker.NonSignerStakesAndSignature memory nonSignerStakesAndSignature
) = _registerSignatoriesAndGetNonSignerStakeAndSignatureRandom(
1, numNonSigners, quorumBitmap
);

// Create invalid G2 point
BN254.G2Point memory invalidG2Point = BN254.G2Point(
[type(uint256).max, type(uint256).max], [type(uint256).max, type(uint256).max]
);

(bool pairingSuccessful, bool signatureIsValid) = blsSignatureChecker
.trySignatureAndApkVerification(
msgHash,
nonSignerStakesAndSignature.quorumApks[0],
invalidG2Point,
nonSignerStakesAndSignature.sigma
);

assertFalse(pairingSuccessful, "Pairing should fail");
assertFalse(signatureIsValid, "Signature should be invalid");
}
}
78 changes: 78 additions & 0 deletions test/unit/OperatorStateRetrieverUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -649,4 +649,82 @@ contract OperatorStateRetrieverUnitTests is MockAVSDeployer {
}
}
}

function test_getBatchOperatorId_emptyArray() public {
address[] memory operators = new address[](0);
bytes32[] memory operatorIds =
operatorStateRetriever.getBatchOperatorId(registryCoordinator, operators);
assertEq(operatorIds.length, 0, "Should return empty array for empty input");
}

function test_getBatchOperatorId_unregisteredOperators() public {
address[] memory operators = new address[](2);
operators[0] = address(1);
operators[1] = address(2);

bytes32[] memory operatorIds =
operatorStateRetriever.getBatchOperatorId(registryCoordinator, operators);

assertEq(operatorIds.length, 2, "Should return array of same length as input");
assertEq(operatorIds[0], bytes32(0), "Unregistered operator should return 0");
assertEq(operatorIds[1], bytes32(0), "Unregistered operator should return 0");
}

function test_getBatchOperatorId_mixedRegistration() public {
// Register one operator
cheats.roll(registrationBlockNumber);
_registerOperatorWithCoordinator(defaultOperator, 1, defaultPubKey);

// Create test array with one registered and one unregistered operator
address[] memory operators = new address[](2);
operators[0] = defaultOperator;
operators[1] = address(2); // unregistered

bytes32[] memory operatorIds =
operatorStateRetriever.getBatchOperatorId(registryCoordinator, operators);

assertEq(operatorIds.length, 2, "Should return array of same length as input");
assertEq(
operatorIds[0], defaultOperatorId, "Should return correct ID for registered operator"
);
assertEq(operatorIds[1], bytes32(0), "Should return 0 for unregistered operator");
}

function test_getBatchOperatorFromId_emptyArray() public {
bytes32[] memory operatorIds = new bytes32[](0);
address[] memory operators =
operatorStateRetriever.getBatchOperatorFromId(registryCoordinator, operatorIds);
assertEq(operators.length, 0, "Should return empty array for empty input");
}

function test_getBatchOperatorFromId_unregisteredIds() public {
bytes32[] memory operatorIds = new bytes32[](2);
operatorIds[0] = bytes32(uint256(1));
operatorIds[1] = bytes32(uint256(2));

address[] memory operators =
operatorStateRetriever.getBatchOperatorFromId(registryCoordinator, operatorIds);

assertEq(operators.length, 2, "Should return array of same length as input");
assertEq(operators[0], address(0), "Unregistered ID should return address(0)");
assertEq(operators[1], address(0), "Unregistered ID should return address(0)");
}

function test_getBatchOperatorFromId_mixedRegistration() public {
// Register one operator
cheats.roll(registrationBlockNumber);
_registerOperatorWithCoordinator(defaultOperator, 1, defaultPubKey);

// Create test array with one registered and one unregistered operator ID
bytes32[] memory operatorIds = new bytes32[](2);
operatorIds[0] = defaultOperatorId;
operatorIds[1] = bytes32(uint256(2)); // unregistered

address[] memory operators =
operatorStateRetriever.getBatchOperatorFromId(registryCoordinator, operatorIds);

assertEq(operators.length, 2, "Should return array of same length as input");
assertEq(operators[0], defaultOperator, "Should return correct address for registered ID");
assertEq(operators[1], address(0), "Should return address(0) for unregistered ID");
}
}
Loading

0 comments on commit 59e22ce

Please sign in to comment.