Skip to content
This repository was archived by the owner on Dec 3, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 215 additions & 0 deletions contracts/ext-interop/tests/ValidatorSetGasTests.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
// (c) 2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

// SPDX-License-Identifier: LicenseRef-Ecosystem

pragma solidity 0.8.25;

import {Test} from "@forge-std/Test.sol";
import {ValidatorSet} from "../validator-set.sol";

contract ValidatorSetGasTests is Test {
ValidatorSet internal _validatorSet;

bytes public constant PUBLIC_KEY =
hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678";

function setUp() public {
_validatorSet = new ValidatorSet();
}

function testGasUsageRegisterValidator() public {
uint256 gasStart = gasleft();

_validatorSet.registerValidator(1000, PUBLIC_KEY);

uint256 gasUsed = gasStart - gasleft();
emit log_named_uint("Gas used for registration", gasUsed);
}

Check warning on line 28 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageRegisterValidator() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#21-28) ignores return value by _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#24)

Check notice on line 28 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageRegisterValidator() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#21-28): External calls: - _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#24) Event emitted after the call(s): - log_named_uint(Gas used for registration,gasUsed) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#27)

function testGasUsageGetValidator() public {
// Register a validator first
uint256 validatorId = _validatorSet.registerValidator(1000, PUBLIC_KEY);

uint256 gasStart = gasleft();

ValidatorSet.Validator memory validator = _validatorSet.getValidator(validatorId);

uint256 gasUsed = gasStart - gasleft();
emit log_named_uint("Gas used for getting validator", gasUsed);

// Ensure the data is correct to avoid optimization issues
assertEq(validator.weight, 1000);
assertEq(validator.publicKey, PUBLIC_KEY);
}

Check notice on line 44 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageGetValidator() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#30-44): External calls: - validatorId = _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#32) Event emitted after the call(s): - log_named_uint(Gas used for getting validator,gasUsed) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#39)

function testGasUsageUpdateValidator() public {
// First register a validator
uint256 validatorId = _validatorSet.registerValidator(1000, PUBLIC_KEY);

// Create new public key for update (different from original)
bytes memory newPublicKey =
hex"fedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcbafedcba";

uint256 gasStart = gasleft();

_validatorSet.updateValidator(validatorId, 2000, newPublicKey);

uint256 gasUsed = gasStart - gasleft();
emit log_named_uint("Gas used for updating validator", gasUsed);

// Verify the update was successful
ValidatorSet.Validator memory updatedValidator = _validatorSet.getValidator(validatorId);
assertEq(updatedValidator.weight, 2000);
assertEq(updatedValidator.publicKey, newPublicKey);
}

Check notice on line 65 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageUpdateValidator() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#46-65): External calls: - validatorId = _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#48) - _validatorSet.updateValidator(validatorId,2000,newPublicKey) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#56) Event emitted after the call(s): - log_named_uint(Gas used for updating validator,gasUsed) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#59)

function testGasUsageMultipleRegistrations() public {
emit log_string("=== Testing gas usage for multiple registrations ===");

// Register first validator
uint256 gasStart1 = gasleft();
_validatorSet.registerValidator(1000, PUBLIC_KEY);
uint256 gasUsed1 = gasStart1 - gasleft();

// Register second validator
uint256 gasStart2 = gasleft();
_validatorSet.registerValidator(2000, PUBLIC_KEY);
uint256 gasUsed2 = gasStart2 - gasleft();

// Register third validator
uint256 gasStart3 = gasleft();
_validatorSet.registerValidator(3000, PUBLIC_KEY);
uint256 gasUsed3 = gasStart3 - gasleft();

emit log_named_uint("Gas used for 1st registration", gasUsed1);
emit log_named_uint("Gas used for 2nd registration", gasUsed2);
emit log_named_uint("Gas used for 3rd registration", gasUsed3);

// Check if gas usage increases with each registration (due to storage costs)
assertTrue(gasUsed1 > 0);
assertTrue(gasUsed2 > 0);
assertTrue(gasUsed3 > 0);
}

Check warning on line 93 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageMultipleRegistrations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#67-93) ignores return value by _validatorSet.registerValidator(2000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#77)

Check warning on line 93 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageMultipleRegistrations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#67-93) ignores return value by _validatorSet.registerValidator(3000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#82)

Check warning on line 93 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageMultipleRegistrations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#67-93) ignores return value by _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#72)

Check notice on line 93 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageMultipleRegistrations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#67-93): External calls: - _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#72) - _validatorSet.registerValidator(2000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#77) - _validatorSet.registerValidator(3000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#82) Event emitted after the call(s): - log_named_uint(Gas used for 1st registration,gasUsed1) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#85) - log_named_uint(Gas used for 2nd registration,gasUsed2) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#86) - log_named_uint(Gas used for 3rd registration,gasUsed3) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#87)

function testGasUsageComparisonDifferentStakeAmounts() public {
emit log_string("=== Testing gas usage for different stake amounts ===");

// Small stake amount
uint256 gasStart1 = gasleft();
_validatorSet.registerValidator(1, PUBLIC_KEY);
uint256 gasUsed1 = gasStart1 - gasleft();

// Large stake amount
uint256 gasStart2 = gasleft();
_validatorSet.registerValidator(type(uint256).max, PUBLIC_KEY);
uint256 gasUsed2 = gasStart2 - gasleft();

emit log_named_uint("Gas used for small stake (1 wei)", gasUsed1);
emit log_named_uint("Gas used for large stake (max uint256)", gasUsed2);

// Gas usage should be similar regardless of stake amount since it's just a uint256
uint256 gasUsageDifference = gasUsed2 > gasUsed1 ? gasUsed2 - gasUsed1 : gasUsed1 - gasUsed2;
emit log_named_uint("Gas usage difference", gasUsageDifference);

// The difference should be reasonable (less than 30000 gas due to array storage initialization)
assertTrue(
gasUsageDifference < 30000, "Gas usage should not vary significantly with stake amount"
);
}

Check warning on line 119 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageComparisonDifferentStakeAmounts() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#95-119) ignores return value by _validatorSet.registerValidator(type()(uint256).max,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#105)

Check warning on line 119 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageComparisonDifferentStakeAmounts() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#95-119) ignores return value by _validatorSet.registerValidator(1,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#100)

Check notice on line 119 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageComparisonDifferentStakeAmounts() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#95-119): External calls: - _validatorSet.registerValidator(1,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#100) - _validatorSet.registerValidator(type()(uint256).max,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#105) Event emitted after the call(s): - log_named_uint(Gas used for small stake (1 wei),gasUsed1) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#108) - log_named_uint(Gas used for large stake (max uint256),gasUsed2) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#109) - log_named_uint(Gas usage difference,gasUsageDifference) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#113)

function testGasUsagePublicKeySameLength() public {
emit log_string("=== Testing gas usage for public keys of same length ===");

// Short public key
uint256 gasStart1 = gasleft();
_validatorSet.registerValidator(1000, PUBLIC_KEY);
uint256 gasUsed1 = gasStart1 - gasleft();

// Medium public key
uint256 gasStart2 = gasleft();
_validatorSet.registerValidator(1000, PUBLIC_KEY);
uint256 gasUsed2 = gasStart2 - gasleft();

// Long public key
uint256 gasStart3 = gasleft();
_validatorSet.registerValidator(1000, PUBLIC_KEY);
uint256 gasUsed3 = gasStart3 - gasleft();

emit log_named_uint("Gas used for short public key (48 bytes)", gasUsed1);
emit log_named_uint("Gas used for medium public key (48 bytes)", gasUsed2);
emit log_named_uint("Gas used for long public key (48 bytes)", gasUsed3);

// All public keys are now 48 bytes, so gas usage should be similar
assertTrue(gasUsed1 > 0, "Gas should be used for registration");
assertTrue(gasUsed2 > 0, "Gas should be used for registration");
assertTrue(gasUsed3 > 0, "Gas should be used for registration");

// Gas usage should be similar since all keys are the same length
uint256 maxGas = gasUsed1 > gasUsed2
? (gasUsed1 > gasUsed3 ? gasUsed1 : gasUsed3)
: (gasUsed2 > gasUsed3 ? gasUsed2 : gasUsed3);
uint256 minGas = gasUsed1 < gasUsed2
? (gasUsed1 < gasUsed3 ? gasUsed1 : gasUsed3)
: (gasUsed2 < gasUsed3 ? gasUsed2 : gasUsed3);
assertTrue(
maxGas - minGas < 30000,
"Gas usage difference should be reasonable for same-length keys"
);
}

Check warning on line 159 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsagePublicKeySameLength() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#121-159) ignores return value by _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#126)

Check warning on line 159 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsagePublicKeySameLength() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#121-159) ignores return value by _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#136)

Check warning on line 159 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsagePublicKeySameLength() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#121-159) ignores return value by _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#131)

Check notice on line 159 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsagePublicKeySameLength() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#121-159): External calls: - _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#126) - _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#131) - _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#136) Event emitted after the call(s): - log_named_uint(Gas used for short public key (48 bytes),gasUsed1) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#139) - log_named_uint(Gas used for medium public key (48 bytes),gasUsed2) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#140) - log_named_uint(Gas used for long public key (48 bytes),gasUsed3) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#141)

function testGasUsageReadOperations() public {
emit log_string("=== Testing gas usage for read operations ===");

// Register some validators first
uint256 validatorId1 = _validatorSet.registerValidator(1000, PUBLIC_KEY);
_validatorSet.registerValidator(2000, PUBLIC_KEY);
_validatorSet.registerValidator(3000, PUBLIC_KEY);

// Test getValidator
uint256 gasStart1 = gasleft();
_validatorSet.getValidator(validatorId1);
uint256 gasUsed1 = gasStart1 - gasleft();

// Test getTotalValidators
uint256 gasStart2 = gasleft();
_validatorSet.getTotalValidators();
uint256 gasUsed2 = gasStart2 - gasleft();

emit log_named_uint("Gas used for getValidator", gasUsed1);
emit log_named_uint("Gas used for getTotalValidators", gasUsed2);

// Read operations should be relatively cheap
assertTrue(gasUsed1 < 10000, "getValidator should be relatively cheap");
assertTrue(gasUsed2 < 5000, "getTotalValidators should be very cheap");
}

Check warning on line 185 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageReadOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#161-185) ignores return value by _validatorSet.registerValidator(3000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#167)

Check warning on line 185 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageReadOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#161-185) ignores return value by _validatorSet.getTotalValidators() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#176)

Check warning on line 185 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageReadOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#161-185) ignores return value by _validatorSet.registerValidator(2000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#166)

Check warning on line 185 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageReadOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#161-185) ignores return value by _validatorSet.getValidator(validatorId1) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#171)

Check notice on line 185 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageReadOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#161-185): External calls: - validatorId1 = _validatorSet.registerValidator(1000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#165) - _validatorSet.registerValidator(2000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#166) - _validatorSet.registerValidator(3000,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#167) Event emitted after the call(s): - log_named_uint(Gas used for getValidator,gasUsed1) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#179) - log_named_uint(Gas used for getTotalValidators,gasUsed2) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#180)

function testGasUsageBatchOperations() public {
emit log_string("=== Testing gas usage for batch operations ===");

address[] memory validators = new address[](5);
validators[0] = address(0x100);
validators[1] = address(0x200);
validators[2] = address(0x300);
validators[3] = address(0x400);
validators[4] = address(0x500);

uint256 totalGasUsed = 0;
uint256 gasStart = gasleft();

// Register 5 validators in sequence
for (uint256 i = 0; i < validators.length; i++) {
uint256 iterationGasStart = gasleft();
_validatorSet.registerValidator(1000 + i, PUBLIC_KEY);
uint256 iterationGasUsed = iterationGasStart - gasleft();
emit log_named_uint(
string(abi.encodePacked("Gas for registration ", vm.toString(i + 1))),
iterationGasUsed
);
}

totalGasUsed = gasStart - gasleft();
emit log_named_uint("Total gas used for 5 registrations", totalGasUsed);
emit log_named_uint("Average gas per registration", totalGasUsed / validators.length);
}

Check warning on line 214 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Unused return

ValidatorSetGasTests.testGasUsageBatchOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#187-214) ignores return value by _validatorSet.registerValidator(1000 + i,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#203)

Check notice on line 214 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Calls inside a loop

ValidatorSetGasTests.testGasUsageBatchOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#187-214) has external calls inside a loop: log_named_uint(string(abi.encodePacked(Gas for registration ,vm.toString(i + 1))),iterationGasUsed) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#205-208)

Check notice on line 214 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Calls inside a loop

ValidatorSetGasTests.testGasUsageBatchOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#187-214) has external calls inside a loop: _validatorSet.registerValidator(1000 + i,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#203)

Check notice on line 214 in contracts/ext-interop/tests/ValidatorSetGasTests.t.sol

View check run for this annotation

GitHub Advanced Security / Slither

Reentrancy vulnerabilities

Reentrancy in ValidatorSetGasTests.testGasUsageBatchOperations() (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#187-214): External calls: - _validatorSet.registerValidator(1000 + i,PUBLIC_KEY) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#203) Event emitted after the call(s): - log_named_uint(string(abi.encodePacked(Gas for registration ,vm.toString(i + 1))),iterationGasUsed) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#205-208) - log_named_uint(Total gas used for 5 registrations,totalGasUsed) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#212) - log_named_uint(Average gas per registration,totalGasUsed / validators.length) (contracts/ext-interop/tests/ValidatorSetGasTests.t.sol#213)
}
68 changes: 68 additions & 0 deletions contracts/ext-interop/validator-set.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.25;

/**
* @title ValidatorSet
* @dev Contract for managing validator information using struct storage in arrays
*/
contract ValidatorSet {
// Struct to represent validator information
struct Validator {
uint256 weight;
bytes publicKey;
}

// Array to store validators
Validator[] public validators;

/**
* @dev Public function to save/register a new validator
* @param weight The weight of the validator
* @param publicKey The public key of the validator
*/
function registerValidator(
uint256 weight,
bytes memory publicKey
) public returns (uint256 validatorId) {
// Create and push the validator struct to the array
validators.push(Validator({weight: weight, publicKey: publicKey}));

// Return the index (validator ID) - arrays are 0-indexed
validatorId = validators.length - 1;
return validatorId;
}

/**
* @dev Public function to update an existing validator's information
* @param validatorId The ID of the validator to update
* @param weight The new weight of the validator
* @param publicKey The new public key of the validator
*/
function updateValidator(uint256 validatorId, uint256 weight, bytes memory publicKey) public {
require(validatorId < validators.length, "Invalid validator ID");

Check notice on line 42 in contracts/ext-interop/validator-set.sol

View check run for this annotation

GitHub Advanced Security / Semgrep PRO

Semgrep Finding: solidity.performance.use-custom-error-not-require.use-custom-error-not-require

Consider using custom errors as they are more gas efficient while allowing developers to describe the error in detail using NatSpec.

Check notice

Code scanning / Semgrep PRO

Semgrep Finding: solidity.performance.use-custom-error-not-require.use-custom-error-not-require Note

Consider using custom errors as they are more gas efficient while allowing developers to describe the error in detail using NatSpec.

// Update the validator struct in the array
validators[validatorId].weight = weight;
validators[validatorId].publicKey = publicKey;
}

/**
* @dev Get validator information by ID
* @param validatorId The ID of the validator
* @return validator The validator struct
*/
function getValidator(
uint256 validatorId
) public view returns (Validator memory) {
require(validatorId < validators.length, "Invalid validator ID");

Check notice on line 57 in contracts/ext-interop/validator-set.sol

View check run for this annotation

GitHub Advanced Security / Semgrep PRO

Semgrep Finding: solidity.performance.use-custom-error-not-require.use-custom-error-not-require

Consider using custom errors as they are more gas efficient while allowing developers to describe the error in detail using NatSpec.

Check notice

Code scanning / Semgrep PRO

Semgrep Finding: solidity.performance.use-custom-error-not-require.use-custom-error-not-require Note

Consider using custom errors as they are more gas efficient while allowing developers to describe the error in detail using NatSpec.
return validators[validatorId];
}

/**
* @dev Get the total number of registered validators
* @return count The total count of validators
*/
function getTotalValidators() public view returns (uint256) {
return validators.length;
}
}
Loading