### Solidity: Interface Naming Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Interface names in Solidity must start with a capital 'I' prefix. This convention clearly identifies interfaces and differentiates them from regular contract definitions. ```solidity interface IERC777 { // ... interface definition } ``` -------------------------------- ### Get Vault Parameters (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Calculates and returns vault parameters based on initialization parameters. This public view function is part of OpNetVaultAutoDeployLogic. ```solidity function getVaultParams(IVault.InitParams memory params) public view returns (uint64, bytes memory) { // Implementation details would go here } ``` -------------------------------- ### Get All Tokens (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Retrieves a list of all available tokens. This internal view function is part of SymbioticCoreConstants and returns an array of strings. ```solidity function allTokens() internal view returns (string[] memory result) { // Implementation details would go here } ``` -------------------------------- ### Get ValSetDriver Configuration Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Retrieves the complete configuration for the validator set driver. This includes details on voting power providers, settlement contracts, and various thresholds. The configuration is returned as a structured object, providing a comprehensive overview of the system's parameters. ```solidity // Get ValSetDriver configuration import {IValSetDriver} from "./src/interfaces/modules/valset-driver/IValSetDriver.sol"; IValSetDriver valSetDriver = IValSetDriver(0x1234567890123456789012345678901234567890); IValSetDriver.Config memory config = valSetDriver.getConfig(); // Result structure: // config.numAggregators = 3 (number of signature aggregators) // config.numCommitters = 2 (number of header committers) // config.committerSlotDuration = 21600 (6 hours per committer slot) // config.votingPowerProviders[0].chainId = 1 (Ethereum mainnet) // config.votingPowerProviders[0].addr = 0xVotingPowerProvider1 // config.keysProvider.chainId = 1 // config.keysProvider.addr = 0xKeyRegistryAddress // config.settlements[0].chainId = 1 // config.settlements[0].addr = 0xSettlement1 // config.settlements[1].chainId = 137 (Polygon) // config.settlements[1].addr = 0xSettlement2 // config.maxVotingPower = 1000000000000000000000000 (1M max per validator) // config.minInclusionVotingPower = 1000000000000000000000 (1K min to be included) // config.maxValidatorsCount = 100 (max 100 validators) // config.requiredKeyTags = [15, 20] (required key types) // config.quorumThresholds[0].keyTag = 15 // config.quorumThresholds[0].quorumThreshold = 6667 (66.67%) // config.requiredHeaderKeyTag = 15 (key tag for header commitments) // config.verificationType = 0 (simple verification) ``` -------------------------------- ### Get Slasher Parameters (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Calculates and returns slasher parameters based on whether it's a burner hook. This public view function is part of OpNetVaultAutoDeployLogic. ```solidity function getSlasherParams(bool isBurnerHook) public view returns (uint64, bytes memory) { // Implementation details would go here } ``` -------------------------------- ### Get Tokenized Vault Parameters (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Calculates and returns tokenized vault parameters based on base parameters, name, and symbol. This function is part of OpNetVaultAutoDeployLogic. ```solidity function getVaultTokenizedParams(IVault.InitParams memory baseParams, string memory name, string memory symbol) // Implementation details would go here ``` -------------------------------- ### KeyRegistry - Get Operator Keys (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Retrieves all cryptographic keys registered for a specific operator at a given point in time. The function returns an array of key structures, each containing a tag and its corresponding payload. This is useful for verifying operator identities and their associated cryptographic material. ```solidity // Get all keys for an operator import {IKeyRegistry} from "./src/interfaces/modules/key-registry/IKeyRegistry.sol"; IKeyRegistry keyRegistry = IKeyRegistry(0x1234567890123456789012345678901234567890); address operator = 0xOperatorAddress; uint48 timestamp = uint48(block.timestamp); IKeyRegistry.Key[] memory keys = keyRegistry.getKeysAt(operator, timestamp); // Result structure: // keys[0].tag = 15 (header key tag) // keys[0].payload = hex"1234..." (BLS public key) // keys[1].tag = 20 (additional key tag) // keys[1].payload = hex"5678..." (ECDSA public key) for (uint i = 0; i < keys.length; i++) { // Process each key by tag if (keys[i].tag == 15) { // This is the header signing key bytes memory headerKey = keys[i].payload; } } ``` -------------------------------- ### Get Veto Slasher Parameters (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Calculates and returns veto slasher parameters based on burner hook status, veto duration, and resolver set epochs delay. This function is part of OpNetVaultAutoDeployLogic. ```solidity function getVetoSlasherParams(bool isBurnerHook, uint48 vetoDuration, uint256 resolverSetEpochsDelay) // Implementation details would go here ``` -------------------------------- ### VotingPowerProvider - Get All Voting Powers (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Retrieves the voting power distribution across all registered operators and their associated vaults. This data is crucial for the ValSetDriver module to construct the validator set. It takes an array of extra data for each operator as input and returns an array of operator voting power structures. ```solidity // Get voting powers for all operators import {IVotingPowerProvider} from "./src/interfaces/modules/voting-power/IVotingPowerProvider.sol"; IVotingPowerProvider votingPowerProvider = IVotingPowerProvider(0x1234567890123456789012345678901234567890); bytes[] memory extraData = new bytes[](2); extraData[0] = ""; // Extra data for operator 1 extraData[1] = ""; // Extra data for operator 2 IVotingPowerProvider.OperatorVotingPower[] memory allVotingPowers = votingPowerProvider.getVotingPowers(extraData); // Result structure: // allVotingPowers[0].operator = 0xOperator1Address // allVotingPowers[0].vaults[0].vault = 0xVault1Address // allVotingPowers[0].vaults[0].value = 1000000000000000000000 // allVotingPowers[1].operator = 0xOperator2Address // allVotingPowers[1].vaults[0].vault = 0xVault2Address // allVotingPowers[1].vaults[0].value = 500000000000000000000 uint256 totalNetworkVotingPower = 0; for (uint i = 0; i < allVotingPowers.length; i++) { for (uint j = 0; j < allVotingPowers[i].vaults.length; j++) { totalNetworkVotingPower += allVotingPowers[i].vaults[j].value; } } ``` -------------------------------- ### Get Operator Voting Powers at Timestamp (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Retrieves the voting power of a specific operator across all vaults at a given historical timestamp. This function accounts for stake-to-voting-power conversion mechanisms. It returns an array of VaultValue structs, each containing a vault address and its corresponding voting power value. An optional extraData parameter can be provided for calculator-specific data. ```solidity // Get operator voting powers at specific timestamp import {IVotingPowerProvider} from "./src/interfaces/modules/voting-power/IVotingPowerProvider.sol"; IVotingPowerProvider votingPowerProvider = IVotingPowerProvider(0x1234567890123456789012345678901234567890); address operator = 0xOperatorAddress; uint48 timestamp = uint48(block.timestamp - 3600); // 1 hour ago bytes memory extraData = ""; // Optional calculator-specific data IVotingPowerProvider.VaultValue[] memory votingPowers = votingPowerProvider.getOperatorVotingPowersAt(operator, extraData, timestamp); // Result structure: // votingPowers[0].vault = 0xVault1Address // votingPowers[0].value = 1000000000000000000000 (1000 tokens worth of voting power) // votingPowers[1].vault = 0xVault2Address // votingPowers[1].value = 500000000000000000000 (500 tokens worth of voting power) uint256 totalVotingPower = 0; for (uint i = 0; i < votingPowers.length; i++) { totalVotingPower += votingPowers[i].value; } // totalVotingPower = 1500000000000000000000 ``` -------------------------------- ### Configure Environment Variables for Deployment Source: https://github.com/symbioticfi/relay-contracts/blob/main/README.md Sets up necessary environment variables for deployment, including RPC URLs and Etherscan API keys. Create a '.env' file based on the provided template to store these sensitive credentials. ```dotenv ETH_RPC_URL= ETHERSCAN_API_KEY= ``` -------------------------------- ### Build, Test, and Format Smart Contracts with Foundry Source: https://github.com/symbioticfi/relay-contracts/blob/main/README.md Standard Foundry commands for compiling, testing, and formatting smart contracts within the project. These commands are essential for maintaining code quality and ensuring contract functionality. ```bash forge build forge test forge fmt ``` -------------------------------- ### Solidity: Import Grouping and Ordering Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Imports in Solidity must be divided into separate groups and ordered alphabetically within each group. The specified order is: contracts, libraries, interfaces, and then external files. ```solidity import {NetworkManager} from "../base/NetworkManager.sol"; import {OzEIP712} from "../base/OzEIP712.sol"; import {PermissionManager} from "../base/PermissionManager.sol"; import {Checkpoints} from "../../libraries/structs/Checkpoints.sol"; import {KeyTags} from "../../libraries/utils/KeyTags.sol"; import {ISettlement} from "../interfaces/modules/settlement/ISettlement.sol"; import {ISigVerifier} from "../interfaces/modules/settlement/sig-verifiers/ISigVerifier.sol"; import {StaticDelegateCallable} from "@symbioticfi/core/src/contracts/common/StaticDelegateCallable.sol"; import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; ``` -------------------------------- ### Deploy Relay Contracts using Bash Script Source: https://github.com/symbioticfi/relay-contracts/blob/main/README.md This bash script orchestrates multi-chain deployments of Relay modules using Foundry scripts and Python for TOML parsing. It deploys contracts via OZ's TransparentUpgradeableProxy and CreateX, requiring a custom Foundry script and a TOML configuration file. ```bash ./script/relay-deploy.sh ./script/examples/MyRelayDeploy.sol ./script/examples/my-relay-deploy.toml --broadcast --ledger ``` -------------------------------- ### Solidity: Comparison with msg.sender or tx.origin Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md When comparing with 'msg.sender' or 'tx.origin' in Solidity, these keywords must be placed on the right side of the inequality. This practice enhances security by preventing certain types of spoofing attacks. ```solidity modifier onlyOwner() internal { if (owner != msg.sender) { revert NotOwner(); } } ``` -------------------------------- ### Solidity: Versioning for Deployable Contracts Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Contracts intended for deployment must specify an explicit Solidity version in their pragma statement. This ensures predictable behavior and prevents unexpected changes due to compiler updates. ```solidity pragma solidity 0.8.X; ``` -------------------------------- ### Solidity: Function Visibility and Order Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Functions within a Solidity contract must be grouped and ordered by visibility: constructor, external, public, internal, and private. This structured approach improves readability and maintainability. ```solidity // 1. constructor // 2. external // 3. public // 4. internal // 5. private // 6. receive function (if exists) // 7. fallback function (if exists) ``` -------------------------------- ### Configure Multi-Chain Relay Deployment with TOML Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Configures multi-chain deployment targets and RPC endpoints for relay infrastructure. This TOML file specifies network configurations, including endpoint URLs for various blockchains, and defines which components to deploy on which networks. It serves as the configuration source for the Solidity deployment script. ```toml # my-relay-deploy.toml - Multi-chain deployment configuration [31337] endpoint_url = "http://127.0.0.1:8545" [1] endpoint_url = "https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY" [137] endpoint_url = "https://polygon-mainnet.g.alchemy.com/v2/YOUR_API_KEY" [42161] endpoint_url = "https://arb-mainnet.g.alchemy.com/v2/YOUR_API_KEY" # Deployment configuration [1234567890] endpoint_url = "" keyRegistry = 1 # Deploy KeyRegistry to Ethereum votingPowerProvider = [1, 137] # Deploy VotingPowerProvider to Ethereum and Polygon settlement = [1, 42161] # Deploy Settlement to Ethereum and Arbitrum valSetDriver = 1 # Deploy ValSetDriver to Ethereum # After deployment, addresses will be automatically filled: # keyRegistry_address = "0x..." # votingPowerProvider_addresses = ["0x...", "0x..."] # settlement_addresses = ["0x...", "0x..."] # valSetDriver_address = "0x..." # Usage: ./script/relay-deploy.sh ./MyRelayDeploy.sol ./my-relay-deploy.toml --broadcast ``` -------------------------------- ### Solidity: Versioning for Abstract Contracts, Libraries, and Interfaces Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Abstract contracts, libraries, and interfaces should use the caret ('^') range operator for their pragma statements to ensure better compatibility across different Solidity versions. For interfaces, a 'greater than or equal to' (>=) operator may be preferred for future compatibility. ```solidity pragma solidity ^0.X.0; // For interfaces, consider: // pragma solidity >=0.X.0; ``` -------------------------------- ### Solidity: Naming Collision Avoidance Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md To avoid naming collisions, particularly with constructor arguments, a single trailing underscore should be used for variable names that match keywords or existing identifiers. This ensures clarity and prevents unintended shadowing. ```solidity contract TestContract { uint256 public foo; constructor(uint256 foo_) { foo = foo_; } } ``` -------------------------------- ### Solidity: Custom Error Naming Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Custom errors in Solidity should be used whenever possible. Their naming should be concise and easy to read, facilitating clear error handling. ```solidity error InsufficientFunds(); error NoAccess(); error NotOwner(); ``` -------------------------------- ### Deploy Custom Relay Infrastructure with Solidity Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Deploys a complete relay infrastructure with custom configurations across multiple chains. This script utilizes the RelayDeploy framework and defines custom implementations for voting power providers, key registries, settlements, and validator set drivers. It requires deployment configurations to be specified in a TOML file. ```solidity // MyRelayDeploy.sol - Custom relay deployment script // SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import {RelayDeploy} from "./script/RelayDeploy.sol"; import {MyVotingPowerProvider} from "./examples/MyVotingPowerProvider.sol"; import {MyKeyRegistry} from "./examples/MyKeyRegistry.sol"; import {MySettlement} from "./examples/MySettlement.sol"; import {MyValSetDriver} from "./examples/MyValSetDriver.sol"; import {IVotingPowerProvider} from "./src/interfaces/modules/voting-power/IVotingPowerProvider.sol"; import {IKeyRegistry} from "./src/interfaces/modules/key-registry/IKeyRegistry.sol"; import {ISettlement} from "./src/interfaces/modules/settlement/ISettlement.sol"; import {IValSetDriver} from "./src/interfaces/modules/valset-driver/IValSetDriver.sol"; contract MyRelayDeploy is RelayDeploy { address public constant OWNER = 0xYourOwnerAddress; uint48 public constant EPOCH_DURATION = 86400; // 24 hours uint208 public constant NUM_AGGREGATORS = 5; uint208 public constant NUM_COMMITTERS = 3; uint256 public constant MAX_VOTING_POWER = 1000000 * 10 ** 18; uint208 public constant MAX_VALIDATORS_COUNT = 100; constructor() RelayDeploy("./config/my-relay-deploy.toml") {} function _votingPowerProviderParams() internal override returns (address implementation, bytes memory initData) { implementation = address(new MyVotingPowerProvider( address(getCore().operatorRegistry), address(getCore().vaultFactory) )); initData = abi.encodeCall( MyVotingPowerProvider.initialize, ( IVotingPowerProvider.VotingPowerProviderInitParams({ networkManagerInitParams: INetworkManager.NetworkManagerInitParams({ network: address(1), subnetworkId: 0 }), ozEip712InitParams: IOzEIP712.OzEIP712InitParams({ name: "MyVotingPowerProvider", version: "1" }), requireSlasher: false, minVaultEpochDuration: 86400, token: address(0) }), IOzOwnable.OzOwnableInitParams({owner: OWNER}) ) ); } function runDeployKeyRegistry() public override { deployKeyRegistry({proxyOwner: OWNER, isDeployerGuarded: true, salt: "KeyReg"}); } } // Deploy with: ./script/relay-deploy.sh ./MyRelayDeploy.sol ./config.toml --broadcast --ledger ``` -------------------------------- ### Solidity: Internal/Private Variable and Function Naming Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Internal or private state variables and functions in Solidity contracts should be prefixed with an underscore. This convention helps distinguish them from public or external members. ```solidity contract TestContract { uint256 private _privateVar; uint256 internal _internalVar; function _testInternal() internal { ... } function _testPrivate() private { ... } } ``` -------------------------------- ### Solidity: Interface Section Separators Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Interfaces in Solidity should be virtually divided into sections using comment separators for ERRORS, STRUCTS, EVENTS, and FUNCTIONS. This organization enhances the readability of interface definitions. ```solidity /* ERRORS */ // ... /* STRUCTS */ // ... /* EVENTS */ // ... /* FUNCTIONS */ // ... ``` -------------------------------- ### Solidity: Abstract Contract Declaration Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Contracts that are not intended for direct deployment and must be inherited by other contracts should be marked as 'abstract'. This enforces a contract inheritance structure. ```solidity abstract contract AccessControl is ..., { // ... abstract contract definition } ``` -------------------------------- ### Solidity: Event Emission Convention Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Events in Solidity should typically be emitted immediately after the state change they represent and named the same as the function causing the change. Exceptions for gas efficiency are allowed if observable event ordering is not affected. ```solidity function _burn(address who, uint256 value) internal { super._burn(who, value); emit Burn(who, value); } ``` -------------------------------- ### Solidity: Contract Section Separators Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md Contracts in Solidity should be divided into sections using specific comment separators for clarity. These sections include CONSTANTS, IMMUTABLES, STATE VARIABLES, MODIFIERS, CONSTRUCTOR, EXTERNAL FUNCTIONS, PUBLIC FUNCTIONS, INTERNAL FUNCTIONS, PRIVATE FUNCTIONS, RECEIVE FUNCTION, and FALLBACK FUNCTION. ```solidity /* CONSTANTS */ // ... /* IMMUTABLES */ // ... /* STATE VARIABLES */ // ... /* MODIFIERS */ // ... /* CONSTRUCTOR */ // ... /* EXTERNAL FUNCTIONS */ // ... /* PUBLIC FUNCTIONS */ // ... /* INTERNAL FUNCTIONS */ // ... /* PRIVATE FUNCTIONS */ // ... /* RECEIVE FUNCTION */ // ... /* FALLBACK FUNCTION */ // ... ``` -------------------------------- ### Solidity: Unchecked Arithmetic Block Commenting Source: https://github.com/symbioticfi/relay-contracts/blob/main/CONTRIBUTING.md When using unchecked arithmetic blocks in Solidity, comments must explain why overflow is guaranteed not to happen or is permissible. If the reason is obvious from the preceding line, the comment can be omitted. ```solidity unchecked { // Reason for unchecked arithmetic // ... arithmetic operations } ``` -------------------------------- ### Implement Weighted Tokens Voting Power Calculator Source: https://context7.com/symbioticfi/relay-contracts/llms.txt This Solidity contract implements a weighted token voting power calculation system. It allows administrators to assign different voting power multipliers (weights) to various tokens. This enables a more nuanced voting system where certain tokens can contribute more or less to an operator's total voting power. It depends on VotingPowerProvider and OzOwnable for initialization and ownership. ```solidity // Implement weighted tokens voting power calculator // SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import {VotingPowerProvider} from "./src/modules/voting-power/VotingPowerProvider.sol"; import {WeightedTokensVPCalc} from "./src/modules/voting-power/common/voting-power-calc/WeightedTokensVPCalc.sol"; import {OzOwnable} from "./src/modules/common/permissions/OzOwnable.sol"; contract WeightedVotingPowerProvider is VotingPowerProvider, OzOwnable, WeightedTokensVPCalc { constructor(address operatorRegistry, address vaultFactory) VotingPowerProvider(operatorRegistry, vaultFactory) {} function initialize( VotingPowerProviderInitParams memory params, OzOwnableInitParams memory ownableParams ) public initializer { __VotingPowerProvider_init(params); __OzOwnable_init(ownableParams); } // Set token weights function setTokenWeight(address token, uint256 weight) external onlyOwner { _setTokenWeight(token, weight); // weight is in basis points (10000 = 1x, 20000 = 2x) // Emits: SetTokenWeight(token, weight) } } // Usage example: // Set WETH to 2x voting power: setTokenWeight(WETH, 20000) // Set USDC to 0.5x voting power: setTokenWeight(USDC, 5000) // 1000 WETH stake = 2000 voting power // 1000 USDC stake = 500 voting power ``` -------------------------------- ### Compare ECDSA Secp256k1 Keys (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Compares two ECDSA secp256k1 keys for equality. This internal view function is provided by the KeyEcdsaSecp256k1 library and returns a boolean. ```solidity function equal(KEY_ECDSA_SECP256K1 memory key1, KEY_ECDSA_SECP256K1 memory key2) internal view returns (bool) { // Implementation details would go here } ``` -------------------------------- ### Zero ECDSA Secp256k1 Key (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Returns a zero-initialized ECDSA secp256k1 key. This internal view function is part of the KeyEcdsaSecp256k1 library. ```solidity function zeroKey() internal view returns (KEY_ECDSA_SECP256K1 memory key) { // Implementation details would go here } ``` -------------------------------- ### Zero BLS12-381 G2 Key (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Returns a zero-initialized BLS12-381 G2 key. This internal view function is part of the KeyBlsBn254 library. ```solidity function zeroKey() internal view returns (KEY_BLS_BN254 memory key) { // Implementation details would go here } ``` -------------------------------- ### Settlement - Commit Validator Set Header (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Commits a new validator set header to the settlement contract, which advances the system to the next epoch. This process involves verifying a quorum signature to ensure consensus. The function takes the header, associated extra data, and a BLS signature proof as input. ```solidity // Commit validator set header import {ISettlement} from "./src/interfaces/modules/settlement/ISettlement.sol"; ISettlement settlement = ISettlement(0x1234567890123456789012345678901234567890); ISettlement.ValSetHeader memory header = ISettlement.ValSetHeader({ version: 1, requiredKeyTag: 15, epoch: 100, captureTimestamp: uint48(block.timestamp - 60), // Captured 60s ago quorumThreshold: 6667, // 66.67% quorum for next epoch totalVotingPower: 1000000000000000000000000, // 1M tokens total validatorsSszMRoot: 0x1234567890abcdef... // SSZ Merkle root of validator set }); ISettlement.ExtraData[] memory extraData = new ISettlement.ExtraData[](1); extraData[0] = ISettlement.ExtraData({ key: keccak256("aggregated_pubkey"), value: bytes32(uint256(0x5678...)) // Aggregated BLS public key }); bytes memory proof = hex"bls_signature_proof..."; // BLS aggregated signature proof // Anyone can commit if they have valid quorum proof settlement.commitValSetHeader(header, extraData, proof); // Reverts with Settlement_InvalidEpoch if epoch <= last committed epoch // Reverts with Settlement_InvalidCaptureTimestamp if timestamp constraints violated // Reverts with Settlement_VerificationFailed if quorum signature invalid // Emits: CommitValSetHeader(header, extraData) ``` -------------------------------- ### Convert BLS12-381 G2 Key to Bytes (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Converts a BLS12-381 G2 key structure into its byte representation. This function is internal to the KeyBlsBn254 library and is marked as 'view'. ```solidity function toBytes(KEY_BLS_BN254 memory key) internal view returns (bytes memory keyBytes) { // Implementation details would go here } ``` -------------------------------- ### KeyRegistry - Set Operator Key (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Registers or updates a cryptographic key for an operator. This function includes ownership verification and supports multiple key types such as BLS BN254, ECDSA secp256k1, and BLS BLS12381. It requires a unique key tag, the public key itself, a signature proving ownership, and potentially a G2 public key for specific BLS schemes. ```solidity // Set BLS BN254 key for operator import {IKeyRegistry, KEY_TYPE_BLS_BN254} from "./src/interfaces/modules/key-registry/IKeyRegistry.sol"; IKeyRegistry keyRegistry = IKeyRegistry(0x1234567890123456789012345678901234567890); uint8 keyTag = 15; // Unique identifier for this key bytes memory blsPublicKey = hex"1234..."; // 48 bytes BLS public key (G1) bytes memory keyOwnershipSignature = hex"signature..."; // BLS signature proving key ownership bytes memory blsG2PublicKey = hex"5678..."; // 96 bytes G2 public key for BLS // Caller sets their own key keyRegistry.setKey(keyTag, blsPublicKey, keyOwnershipSignature, blsG2PublicKey); // Reverts with KeyRegistry_InvalidKeySignature if signature doesn't prove ownership // Reverts with KeyRegistry_AlreadyUsed if key is used by another operator or with different tag // Emits: SetKey(msg.sender, keyTag, blsPublicKey, blsG2PublicKey) ``` -------------------------------- ### Convert ECDSA Secp256k1 Key to Bytes (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Converts an ECDSA secp256k1 key structure into its byte representation. This internal view function is provided by the KeyEcdsaSecp256k1 library. ```solidity function toBytes(KEY_ECDSA_SECP256K1 memory key) internal view returns (bytes memory keyBytes) { // Implementation details would go here } ``` -------------------------------- ### Compare BLS12-381 G2 Keys (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Compares two BLS12-381 G2 keys for equality. This internal view function is provided by the KeyBlsBn254 library and returns a boolean. ```solidity function equal(KEY_BLS_BN254 memory key1, KEY_BLS_BN254 memory key2) internal view returns (bool) { // Implementation details would go here } ``` -------------------------------- ### Implement Operator Whitelist for Voting Power Source: https://context7.com/symbioticfi/relay-contracts/llms.txt This Solidity contract extends VotingPowerProvider to implement an operator whitelist. It restricts which operators can participate in the validator set by using the OperatorsWhitelist module. Only addresses explicitly added to the whitelist by an owner can register as operators. This requires the OzOwnable contract for ownership management. ```solidity // Implement VotingPowerProvider with whitelist // SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import {VotingPowerProvider} from "./src/modules/voting-power/VotingPowerProvider.sol"; import {OperatorsWhitelist} from "./src/modules/voting-power/extensions/OperatorsWhitelist.sol"; import {EqualStakeVPCalc} from "./src/modules/voting-power/common/voting-power-calc/EqualStakeVPCalc.sol"; import {OzOwnable} from "./src/modules/common/permissions/OzOwnable.sol"; contract WhitelistedVotingPowerProvider is VotingPowerProvider, OzOwnable, EqualStakeVPCalc, OperatorsWhitelist { constructor(address operatorRegistry, address vaultFactory) VotingPowerProvider(operatorRegistry, vaultFactory) {} function initialize( VotingPowerProviderInitParams memory params, OzOwnableInitParams memory ownableParams ) public initializer { __VotingPowerProvider_init(params); __OzOwnable_init(ownableParams); } // Add operators to whitelist function addToWhitelist(address operator) external onlyOwner { _addOperatorToWhitelist(operator); // Emits: AddOperatorToWhitelist(operator) } // Remove from whitelist function removeFromWhitelist(address operator) external onlyOwner { _removeOperatorFromWhitelist(operator); // Emits: RemoveOperatorFromWhitelist(operator) // Also unregisters the operator automatically } } // Usage: // Only whitelisted operators can call registerOperator() // Attempting registration without whitelist reverts with OperatorsWhitelist_NotWhitelisted ``` -------------------------------- ### Add Voting Power Provider to ValSetDriver Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Adds a new cross-chain voting power provider to the validator set driver. This allows aggregation of operator stakes from multiple chains, enhancing the distributed nature of the validator set. Requires the MANAGE_VOTING_POWER_PROVIDERS_ROLE. ```solidity // Add voting power provider import {IValSetDriver} from "./src/interfaces/modules/valset-driver/IValSetDriver.sol"; IValSetDriver valSetDriver = IValSetDriver(0x1234567890123456789012345678901234567890); IValSetDriver.CrossChainAddress memory newProvider = IValSetDriver.CrossChainAddress({ chainId: 137, // Polygon chain ID addr: 0xPolygonVotingPowerProvider }); // Requires MANAGE_VOTING_POWER_PROVIDERS_ROLE valSetDriver.addVotingPowerProvider(newProvider); // Reverts with ValSetDriver_ChainAlreadyAdded if same chain ID already exists // Reverts with ValSetDriver_InvalidCrossChainAddress if address is zero or chainId is zero // Emits: AddVotingPowerProvider(newProvider) // Now operators on Polygon can participate in validator set ``` -------------------------------- ### Serialize ECDSA Secp256k1 Key (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Serializes an ECDSA secp256k1 key structure into a byte array. This internal view function is provided by the KeyEcdsaSecp256k1 library. ```solidity function serialize(KEY_ECDSA_SECP256K1 memory key) internal view returns (bytes memory keySerialized) { // Implementation details would go here } ``` -------------------------------- ### Unwrap ECDSA Secp256k1 Key (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Unwraps an ECDSA secp256k1 key structure into its raw address representation. This internal view function is part of the KeyEcdsaSecp256k1 library. ```solidity function unwrap(KEY_ECDSA_SECP256K1 memory key) internal view returns (address keyRaw) { // Implementation details would go here } ``` -------------------------------- ### Solidity: Unnamed Return Variable Warning Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt This warning (6321) indicates that a function has an unnamed return variable which might remain unassigned. It suggests explicitly returning a value or naming the variable to ensure all code paths return correctly. This is common in functions interacting with external data sources like Chainlink price feeds. ```Solidity function getRoundData(address aggregator, uint80 roundId) public view returns (bool, RoundData memory roundData) { // ... implementation ... // Example: Explicitly return roundData if assigned // if (success) return (true, roundData); // return (false, RoundData memory); } function getLatestRoundData(address aggregator) public view returns (bool, RoundData memory roundData) { // ... implementation ... // Example: Explicitly return roundData if assigned // if (success) return (true, roundData); // return (false, RoundData memory); } ``` -------------------------------- ### Solidity: Restrict Function Mutability to Pure Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt This warning (2018) suggests that certain view functions can be marked as 'pure' because they do not read from or modify the state of the contract. Making functions pure can lead to gas optimizations and clearer intent. This applies to key manipulation functions in KeyBlsBls12381 library. ```Solidity function unwrap(KEY_BLS_BLS12381 memory key) internal pure returns (BLS12381.G1Point memory keyRaw) { // ... implementation that only uses input parameters ... // return computedValue; } function toBytes(KEY_BLS_BLS12381 memory key) internal pure returns (bytes memory keyBytes) { // ... implementation that only uses input parameters ... // return computedValue; } function zeroKey() internal pure returns (KEY_BLS_BLS12381 memory key) { // ... implementation that returns a constant value ... // return KEY_BLS_BLS12381(0, 0, 0, 0); } function equal(KEY_BLS_BLS12381 memory key1, KEY_BLS_BLS12381 memory key2) internal pure returns (bool) { // ... implementation that only compares input parameters ... // return key1.field1 == key2.field1 && ...; } ``` -------------------------------- ### Verify ECDSA Secp256k1 Signature (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Verifies an ECDSA secp256k1 signature against a message and a public key. This internal view function is part of the SigEcdsaSecp256k1 library and returns a boolean. ```solidity function verify(address key, bytes32 message, bytes memory signature) internal view returns (bool) { // Implementation details would go here } ``` -------------------------------- ### Deserialize ECDSA Secp256k1 Key (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Deserializes a byte array into an ECDSA secp256k1 key structure. This internal view function is part of the KeyEcdsaSecp256k1 library. ```solidity function deserialize(bytes memory keySerialized) internal view returns (KEY_ECDSA_SECP256K1 memory key) { // Implementation details would go here } ``` -------------------------------- ### Unwrap BLS12-381 G2 Key (Solidity) Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt Unwraps a BLS12-381 G2 key structure into its raw G1Point representation. This function is part of the KeyBlsBn254 library and is marked as 'internal view'. ```solidity function unwrap(KEY_BLS_BN254 memory key) internal view returns (BN254.G1Point memory keyRaw) { // Implementation details would go here } ``` -------------------------------- ### Verify Quorum Signature for Settlement Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Verifies an aggregated signature from the validator set for arbitrary messages. This function is crucial for cross-chain message attestation and is used in scenarios like cross-chain bridges, oracle updates, and governance votes. It returns a boolean indicating validity and does not revert on failure. ```solidity // Verify quorum signature for a message import {ISettlement} from "./src/interfaces/modules/settlement/ISettlement.sol"; ISettlement settlement = ISettlement(0x1234567890123456789012345678901234567890); bytes memory message = abi.encodePacked( keccak256("CROSS_CHAIN_MESSAGE"), uint256(12345), // destination chain ID address(0xTargetContract), bytes4(0x12345678) // function selector ); uint8 keyTag = 15; // Use header key tag uint256 quorumThreshold = 6667; // Require 66.67% of voting power bytes memory proof = hex"aggregated_bls_signature..."; uint48 epoch = 99; // Verify against epoch 99 validator set bytes memory hint = ""; // Optional optimization hint bool isValid = settlement.verifyQuorumSigAt( message, keyTag, quorumThreshold, proof, epoch, hint ); // Result: isValid = true if quorum signature is valid // Returns: false if verification fails (doesn't revert) // Use case: Cross-chain bridges, oracle updates, governance votes if (isValid) { // Execute cross-chain action ITargetContract(0xTargetContract).executeAction(); } ``` -------------------------------- ### Register Operator with Signature in VotingPowerProvider (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Registers an operator in the VotingPowerProvider contract using an EIP-712 signature. This allows a third party to submit the registration on behalf of the operator. The function validates the signature and reverts if it's invalid or if the operator is already registered. It emits a RegisterOperator event upon successful registration. ```solidity // Register operator with signature import {IVotingPowerProvider} from "./src/interfaces/modules/voting-power/IVotingPowerProvider.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; address operatorAddress = 0xOperatorAddress; bytes memory signature = hex"signature_bytes_here"; IVotingPowerProvider votingPowerProvider = IVotingPowerProvider(0x1234567890123456789012345678901234567890); // Anyone can call this with a valid signature from the operator votingPowerProvider.registerOperatorWithSignature(operatorAddress, signature); // Reverts with VotingPowerProvider_InvalidSignature if signature is invalid // Reverts with VotingPowerProvider_OperatorAlreadyRegistered if already registered // Emits: RegisterOperator(operatorAddress) ``` -------------------------------- ### Register Operator in VotingPowerProvider (Solidity) Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Registers an operator in the VotingPowerProvider contract. This function requires the operator to be pre-registered in the core OperatorRegistry. The caller directly registers themselves as an operator. This action emits a RegisterOperator event. ```solidity // Register operator with direct call import {IVotingPowerProvider} from "./src/interfaces/modules/voting-power/IVotingPowerProvider.sol"; address votingPowerProviderAddress = 0x1234567890123456789012345678901234567890; IVotingPowerProvider votingPowerProvider = IVotingPowerProvider(votingPowerProviderAddress); // Caller registers themselves as an operator votingPowerProvider.registerOperator(); // Emits: RegisterOperator(msg.sender) // Result: Operator is now registered and can participate in the validator set ``` -------------------------------- ### Set Epoch Duration in ValSetDriver Source: https://context7.com/symbioticfi/relay-contracts/llms.txt Updates the epoch duration for validator set rotation. This parameter controls the frequency at which the validator set can be updated. Setting a new duration requires the SET_EPOCH_DURATION_ROLE and will emit a SetEpochDuration event upon successful execution. ```solidity // Set epoch duration import {IEpochManager} from "./src/interfaces/modules/valset-driver/IEpochManager.sol"; IEpochManager epochManager = IEpochManager(valSetDriverAddress); uint48 newEpochDuration = 86400; // 24 hours in seconds // Requires SET_EPOCH_DURATION_ROLE epochManager.setEpochDuration(newEpochDuration); // Reverts with EpochManager_InvalidEpochDuration if duration is 0 // Emits: SetEpochDuration(newEpochDuration) // Calculate current epoch uint48 currentEpoch = epochManager.getCurrentEpoch(); // currentEpoch = (block.timestamp - startTime) / 86400 ``` -------------------------------- ### Solidity: Unused Function Parameter Warning Source: https://github.com/symbioticfi/relay-contracts/blob/main/gas.txt This warning (5667) flags function parameters that are declared but not used within the function body. It's recommended to remove or comment out unused parameters to improve code clarity and maintainability. This warning appears in various binding contract functions. ```Solidity function someFunction(...) returns (uint256 depositedAmount, uint256 mintedShares) { // depositedAmount is not used // ... function body ... return (0, 0); // Example return } function anotherFunction(...) returns (uint256 burnedShares, uint256 mintedShares) { // mintedShares is not used // ... function body ... return (0, 0); // Example return } function yetAnotherFunction(...) returns (uint256 withdrawnAssets, uint256 mintedShares) { // mintedShares is not used // ... function body ... return (0, 0); // Example return } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.