Skip to content
Open

Ssv #106

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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/Vectorized/solady
[submodule "lib/based-applications"]
path = lib/based-applications
url = https://github.com/ssvlabs/based-applications
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ remappings = [
"@solady/=lib/solady/src",

"@symbiotic-middleware-sdk/=lib/middleware-sdk/src/",
"@ssv-based-apps/=lib/based-applications/src/",

"lib/eigenlayer-contracts/:@openzeppelin/=lib/eigenlayer-contracts/lib/openzeppelin-contracts-v4.9.0/",
"lib/eigenlayer-contracts/:@openzeppelin-v4.9.0/=lib/eigenlayer-contracts/lib/openzeppelin-contracts-v4.9.0/contracts/",
Expand Down
1 change: 1 addition & 0 deletions lib/based-applications
Submodule based-applications added at 2502cb
65 changes: 65 additions & 0 deletions src/interfaces/IBasedApp.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.27;

import { IBasedAppManager } from "./IBasedAppManager.sol";

/// @title IBasedApp
/// @notice SSV IBasedApp interface (compatible with Solidity 0.8.27)
/// @dev Based on: https://github.com/ssvlabs/based-applications/blob/main/src/middleware/interfaces/IBasedApp.sol
/// Note: Due to version incompatibility (SSV uses 0.8.30, we use 0.8.27), we recreate the interface
interface IBasedApp {
/// @notice Registers the bApp with SSV network
/// @param tokenConfigs Array of token configurations for the bApp
/// @param metadataURI Metadata URI for the bApp
function registerBApp(
IBasedAppManager.TokenConfig[] calldata tokenConfigs,
string calldata metadataURI
)
external;

/// @notice Allows operators to opt into the bApp with specific strategies
/// @param strategyId The strategy ID to opt into
/// @param tokens Array of token addresses
/// @param obligationPercentages Array of obligation percentages for each token
/// @param data Additional data for the opt-in process
/// @return success Whether the opt-in was successful
function optInToBApp(
uint32 strategyId,
address[] calldata tokens,
uint32[] calldata obligationPercentages,
bytes calldata data
)
external
returns (bool success);

/// @notice Handles slashing for validators
/// @param strategyId The strategy ID being slashed
/// @param token The token being slashed
/// @param percentage The slashing percentage
/// @param sender The address initiating the slash
/// @param data Additional slashing data
/// @return success Whether the slash was successful
/// @return receiver The address receiving slashed funds
/// @return exit Whether the validator should exit
function slash(
uint32 strategyId,
address token,
uint32 percentage,
address sender,
bytes calldata data
)
external
returns (bool success, address receiver, bool exit);

/// @notice Updates the metadata URI for the bApp
/// @param metadataURI New metadata URI
function updateBAppMetadataURI(string calldata metadataURI) external;

/// @notice Updates the token configurations for the bApp
/// @param tokenConfigs New token configurations
function updateBAppTokens(IBasedAppManager.TokenConfig[] calldata tokenConfigs)
external;

/// @notice Error thrown when an unauthorized caller attempts to access a restricted function
error UnauthorizedCaller();
}
34 changes: 34 additions & 0 deletions src/interfaces/IBasedAppManager.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.27;

/// @title IBasedAppManager
/// @notice SSV IBasedAppManager interface (compatible with Solidity 0.8.27)
/// @dev Based on: https://github.com/ssvlabs/based-applications/blob/main/src/core/interfaces/IBasedAppManager.sol
/// Note: Due to version incompatibility (SSV uses 0.8.30, we use 0.8.27), we recreate the interface
interface IBasedAppManager {
/// @notice Token configuration struct
struct TokenConfig {
address token;
uint32 sharedRiskLevel;
}

event BAppMetadataURIUpdated(address indexed bApp, string metadataURI);
event BAppRegistered(
address indexed bApp, TokenConfig[] tokenConfigs, string metadataURI
);
event BAppTokensUpdated(address indexed bApp, TokenConfig[] tokenConfigs);

function registerBApp(
TokenConfig[] calldata tokenConfigs,
string calldata metadataURI
)
external;
function updateBAppMetadataURI(string calldata metadataURI) external;
function updateBAppsTokens(TokenConfig[] calldata tokenConfigs) external;

error BAppAlreadyRegistered();
error BAppDoesNotSupportInterface();
error BAppNotRegistered();
error TokenAlreadyAddedToBApp(address token);
error ZeroAddressNotAllowed();
}
223 changes: 223 additions & 0 deletions src/interfaces/ISsvBasedAppMiddleware.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.27;

import { IBasedApp } from "./IBasedApp.sol";
import { IBasedAppManager } from "./IBasedAppManager.sol";
import { ITaiyiRegistryCoordinator } from "./ITaiyiRegistryCoordinator.sol";
import { IERC165 } from
"@openzeppelin-contracts/contracts/utils/introspection/IERC165.sol";
import { IRegistry } from "@urc/IRegistry.sol";
import { ISlasher } from "@urc/ISlasher.sol";
import { BLS } from "@urc/lib/BLS.sol";

/// @title ISsvBasedAppMiddleware
/// @notice Interface for SSV-based application middleware (compatible with Solidity 0.8.27)
/// @dev Based on: https://github.com/ssvlabs/based-applications/blob/main/src/middleware/interfaces/IBasedApp.sol
/// Extended with additional SSV-specific functionality for Linglong integration
interface ISsvBasedAppMiddleware is IERC165 {
// ==============================================================================================
// ================================= STRUCTS ===================================================
// ==============================================================================================

/// @notice Configuration struct for SSV middleware initialization
struct Config {
address registryCoordinator;
address registry;
address slasher;
address gatewayOperatorSet;
address gatewayNetwork;
uint256 registrationMinCollateral;
address ssvBasedAppsNetwork;
}

/// @notice Parameters for gateway delegation
struct GatewayDelegationParams {
address gatewayOperator;
address gatewayNetwork;
bytes signature;
uint256 expiry;
}

// ==============================================================================================
// ================================= CORE BASEDAPP FUNCTIONS (from canonical IBasedApp) =======
// ==============================================================================================

/// @notice Allows operators to opt into the bApp
/// @param strategyId The strategy ID to opt into
/// @param tokens Array of token addresses
/// @param obligationPercentages Array of obligation percentages for each token
/// @param data Additional data for the opt-in process
/// @return success Whether the opt-in was successful
function optInToBApp(
uint32 strategyId,
address[] calldata tokens,
uint32[] calldata obligationPercentages,
bytes calldata data
)
external
returns (bool success);

/// @notice Registers the bApp
/// @param tokenConfigs Array of token configurations for the bApp
/// @param metadataURI Metadata URI for the bApp
function registerBApp(
IBasedAppManager.TokenConfig[] calldata tokenConfigs,
string calldata metadataURI
)
external;

/// @notice Handles slashing for the bApp
/// @param strategyId The strategy ID being slashed
/// @param token The token being slashed
/// @param percentage The slashing percentage
/// @param sender The address initiating the slash
/// @param data Additional slashing data
/// @return success Whether the slash was successful
/// @return receiver The address receiving slashed funds
/// @return exit Whether the validator should exit
function slash(
uint32 strategyId,
address token,
uint32 percentage,
address sender,
bytes calldata data
)
external
returns (bool success, address receiver, bool exit);

/// @notice Updates the metadata URI for the bApp
/// @param metadataURI New metadata URI
function updateBAppMetadataURI(string calldata metadataURI) external;

/// @notice Updates the token configurations for the bApp
/// @param tokenConfigs New token configurations
function updateBAppTokens(IBasedAppManager.TokenConfig[] calldata tokenConfigs)
external;

// ==============================================================================================
// ================================= SSV-SPECIFIC FUNCTIONS ===================================
// ==============================================================================================

/// @notice Registers validators with the SSV network
/// @param registrations Array of validator registration parameters
/// @return registrationRoot The root hash of the registration
function registerValidators(IRegistry.SignedRegistration[] calldata registrations)
external
payable
returns (bytes32 registrationRoot);

/// @notice Unregisters validators from the SSV network
/// @param registrationRoot The registration root to unregister
function unregisterValidators(bytes32 registrationRoot) external;

/// @notice Opts into gateway delegation for SSV network
/// @param params Gateway delegation parameters
function optInToGatewayDelegation(GatewayDelegationParams calldata params) external;

/// @notice Batch sets delegations for validators
/// @param registrationRoot The registration root containing the validators
/// @param pubkeys BLS public keys of the validators
/// @param delegations New delegation information
function batchSetDelegations(
bytes32 registrationRoot,
BLS.G1Point[] calldata pubkeys,
ISlasher.SignedDelegation[] calldata delegations
)
external;

/// @notice Opts in to the slasher contract for a registration root
/// @param registrationRoot The registration root to opt in
/// @param registrations Array of validator registrations
/// @param delegationSignatures BLS signatures authorizing delegation
/// @param delegateePubKey BLS public key of the delegatee
/// @param delegateeAddress Address of the delegatee
/// @param data Additional data for the registrations
function optInToSlasher(
bytes32 registrationRoot,
IRegistry.SignedRegistration[] calldata registrations,
BLS.G2Point[] calldata delegationSignatures,
BLS.G1Point calldata delegateePubKey,
address delegateeAddress,
bytes[] calldata data
)
external;

// ==============================================================================================
// ================================= VIEW FUNCTIONS ============================================
// ==============================================================================================

/// @notice Gets all registration roots for an operator
/// @param operator The operator address
/// @return Array of registration roots
function getOperatorRegistrationRoots(address operator)
external
view
returns (bytes32[] memory);

/// @notice Gets all delegations for an operator under a registration root
/// @param operator The operator address
/// @param registrationRoot The registration root
/// @return pubkeys Array of BLS public keys
/// @return delegations Array of signed delegations
function getAllDelegations(
address operator,
bytes32 registrationRoot
)
external
view
returns (
BLS.G1Point[] memory pubkeys,
ISlasher.SignedDelegation[] memory delegations
);

/// @notice Gets the registry coordinator
/// @return Registry coordinator address
function getRegistryCoordinator() external view returns (ITaiyiRegistryCoordinator);

/// @notice Gets the gateway operator set address
/// @return Gateway operator set address
function getGatewayOperatorSet() external view returns (address);

/// @notice Gets the gateway network address
/// @return Gateway network address
function getGatewayNetwork() external view returns (address);

// ==============================================================================================
// ================================= EVENTS ====================================================
// ==============================================================================================

/// @notice Emitted when validators are registered with SSV network
event ValidatorsRegistered(
address indexed operator, bytes32 indexed registrationRoot
);

/// @notice Emitted when validators are unregistered from SSV network
event ValidatorsUnregistered(
address indexed operator, bytes32 indexed registrationRoot
);

/// @notice Emitted when operator opts into gateway delegation
event GatewayDelegationOptedIn(
address indexed operator,
address indexed gatewayOperator,
address indexed gatewayNetwork
);

/// @notice Emitted when delegations are batch set
event DelegationsBatchSet(
address indexed operator, bytes32 indexed registrationRoot, uint256 count
);

/// @notice Emitted when slasher is opted into
event SlasherOptedIn(
address indexed operator,
bytes32 indexed registrationRoot,
address indexed delegatee
);

// ==============================================================================================
// ================================= ERRORS ====================================================
// ==============================================================================================

// Note: UnauthorizedCaller() error is inherited from IBasedApp
}
7 changes: 7 additions & 0 deletions src/libs/OperatorSubsetLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ library OperatorSubsetLib {
uint32 constant EIGENLAYER_UNDERWRITER_SUBSET_ID = 1;
uint32 constant SYMBIOTIC_VALIDATOR_SUBSET_ID = 2;
uint32 constant SYMBIOTIC_UNDERWRITER_SUBSET_ID = 3;
uint32 constant SSV_VALIDATOR_SUBSET_ID = 4;
uint32 constant SSV_UNDERWRITER_SUBSET_ID = 5;

/// @notice Structure to store linglong subsets with their members
struct LinglongSubsets {
Expand Down Expand Up @@ -51,6 +53,11 @@ library OperatorSubsetLib {
return linglongSubsetId == SYMBIOTIC_VALIDATOR_SUBSET_ID
|| linglongSubsetId == SYMBIOTIC_UNDERWRITER_SUBSET_ID;
}

function isSSVProtocolID(uint32 linglongSubsetId) internal pure returns (bool) {
return linglongSubsetId == SSV_VALIDATOR_SUBSET_ID
|| linglongSubsetId == SSV_UNDERWRITER_SUBSET_ID;
}
/// @notice Creates a linglong subset with protocol information using uint32 ID
/// @dev Uses uint32 for linglong subset IDs
/// @param linglongSubsets The storage reference to linglong subsets mapping
Expand Down
Loading