Skip to content
Merged
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
13 changes: 8 additions & 5 deletions src/contracts/interfaces/ICrossChainRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ interface ICrossChainRegistryErrors {

/// @notice Thrown when the storage is not cleared
error NeedToDelete();

/// @notice Thrown when the lengths between two arrays are not the same
error ArrayLengthMismatch();
}

interface ICrossChainRegistryTypes {
Expand Down Expand Up @@ -77,7 +80,7 @@ interface ICrossChainRegistryEvents is ICrossChainRegistryTypes {
event TransportDestinationRemoved(OperatorSet operatorSet, uint256 chainID);

/// @notice Emitted when a chainID is added to the whitelist
event ChainIDAddedToWhitelist(uint256 chainID);
event ChainIDAddedToWhitelist(uint256 chainID, address operatorTableUpdater);

/// @notice Emitted when a chainID is removed from the whitelist
event ChainIDRemovedFromWhitelist(uint256 chainID);
Expand Down Expand Up @@ -150,11 +153,10 @@ interface ICrossChainRegistry is ICrossChainRegistryErrors, ICrossChainRegistryE
/**
* @notice Adds chainIDs to the whitelist of chainIDs that can be transported to
* @param chainIDs the chainIDs to add to the whitelist
* @param operatorTableUpdaters the operatorTableUpdaters for each whitelisted chainID
* @dev msg.sender must be the owner of the CrossChainRegistry
*/
function addChainIDsToWhitelist(
uint256[] calldata chainIDs
) external;
function addChainIDsToWhitelist(uint256[] calldata chainIDs, address[] calldata operatorTableUpdaters) external;

/**
* @notice Removes chainIDs from the whitelist of chainIDs that can be transported to
Expand Down Expand Up @@ -228,6 +230,7 @@ interface ICrossChainRegistry is ICrossChainRegistryErrors, ICrossChainRegistryE
/**
* @notice Gets the list of chains that are supported by the CrossChainRegistry
* @return An array of chainIDs that are supported by the CrossChainRegistry
* @return An array of operatorTableUpdaters corresponding to each chainID
*/
function getSupportedChains() external view returns (uint256[] memory);
function getSupportedChains() external view returns (uint256[] memory, address[] memory);
}
6 changes: 3 additions & 3 deletions src/contracts/interfaces/IOperatorTableUpdater.sol
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ interface IOperatorTableUpdater is
* @param globalTableRoot the new globalTableRoot
* @param operatorSetIndex the index of the given operatorSet being updated
* @param proof the proof of the leaf at index against the globalTableRoot
* @param tableInfo the tableInfo of the operator table
* @dev Depending on the decoded KeyType, the tableInfo will be decoded to a
* @param operatorTableBytes the bytes of the operator table
* @dev Depending on the decoded KeyType, the tableInfo will be decoded
*/
function updateOperatorTable(
uint32 referenceTimestamp,
bytes32 globalTableRoot,
uint32 operatorSetIndex,
bytes calldata proof,
bytes calldata tableInfo
bytes calldata operatorTableBytes
) external;

/**
Expand Down
24 changes: 19 additions & 5 deletions src/contracts/multichain/CrossChainRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ contract CrossChainRegistry is
PermissionControllerMixin,
SemVerMixin
{
using EnumerableMap for EnumerableMap.UintToAddressMap;
using EnumerableSet for EnumerableSet.Bytes32Set;
using EnumerableSet for EnumerableSet.UintSet;
using OperatorSetLib for OperatorSet;
Expand Down Expand Up @@ -205,18 +206,21 @@ contract CrossChainRegistry is

/// @inheritdoc ICrossChainRegistry
function addChainIDsToWhitelist(
uint256[] calldata chainIDs
uint256[] calldata chainIDs,
address[] calldata operatorTableUpdaters
Comment on lines +209 to +210
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either make this into an array of structs or add an extra validation for length check between these 2 arrays.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

) external onlyOwner onlyWhenNotPaused(PAUSED_CHAIN_WHITELIST) {
require(chainIDs.length == operatorTableUpdaters.length, ArrayLengthMismatch());

for (uint256 i = 0; i < chainIDs.length; i++) {
uint256 chainID = chainIDs[i];

// Validate chainID
require(chainID != 0, InvalidChainId());

// Add to whitelist
require(_whitelistedChainIDs.add(chainID), ChainIDAlreadyWhitelisted());
require(_whitelistedChainIDs.set(chainID, operatorTableUpdaters[i]), ChainIDAlreadyWhitelisted());

emit ChainIDAddedToWhitelist(chainID);
emit ChainIDAddedToWhitelist(chainID, operatorTableUpdaters[i]);
}
}

Expand Down Expand Up @@ -438,7 +442,17 @@ contract CrossChainRegistry is
}

/// @inheritdoc ICrossChainRegistry
function getSupportedChains() external view returns (uint256[] memory) {
return _whitelistedChainIDs.values();
function getSupportedChains() external view returns (uint256[] memory, address[] memory) {
uint256 length = _whitelistedChainIDs.length();
uint256[] memory chainIDs = new uint256[](length);
address[] memory operatorTableUpdaters = new address[](length);

for (uint256 i = 0; i < length; i++) {
(uint256 chainID, address operatorTableUpdater) = _whitelistedChainIDs.at(i);
chainIDs[i] = chainID;
operatorTableUpdaters[i] = operatorTableUpdater;
}

return (chainIDs, operatorTableUpdaters);
}
}
8 changes: 5 additions & 3 deletions src/contracts/multichain/CrossChainRegistryStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.27;

import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import "../interfaces/ICrossChainRegistry.sol";
import "../interfaces/IOperatorTableCalculator.sol";
import "../interfaces/IAllocationManager.sol";
Expand All @@ -15,6 +16,7 @@ import "../libraries/OperatorSetLib.sol";
* @dev This abstract contract is designed to be inherited by the CrossChainRegistry implementation
*/
abstract contract CrossChainRegistryStorage is ICrossChainRegistry {
using EnumerableMap for EnumerableMap.UintToAddressMap;
using EnumerableSet for EnumerableSet.Bytes32Set;
using EnumerableSet for EnumerableSet.UintSet;
using OperatorSetLib for OperatorSet;
Expand Down Expand Up @@ -62,8 +64,8 @@ abstract contract CrossChainRegistryStorage is ICrossChainRegistry {

/// CHAIN WHITELISTING

/// @dev Set of whitelisted chain IDs that can be used as transport destinations
EnumerableSet.UintSet internal _whitelistedChainIDs;
/// @dev Map of whitelisted chain IDs to operator table updaters
EnumerableMap.UintToAddressMap internal _whitelistedChainIDs;

// Construction

Expand All @@ -77,5 +79,5 @@ abstract contract CrossChainRegistryStorage is ICrossChainRegistry {
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[43] private __gap;
uint256[42] private __gap;
}
10 changes: 5 additions & 5 deletions src/contracts/multichain/OperatorTableUpdater.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ contract OperatorTableUpdater is Initializable, OwnableUpgradeable, OperatorTabl
bytes32 globalTableRoot,
uint32 operatorSetIndex,
bytes calldata proof,
bytes calldata tableInfo
bytes calldata operatorTableBytes
) external {
(OperatorSet memory operatorSet, CurveType curveType, OperatorSetConfig memory operatorSetConfig) =
_getOperatorTableInfo(tableInfo);
_getOperatorTableInfo(operatorTableBytes);

// Check that the `referenceTimestamp` is greater than the latest reference timestamp
require(
Expand All @@ -107,17 +107,17 @@ contract OperatorTableUpdater is Initializable, OwnableUpgradeable, OperatorTabl
globalTableRoot: globalTableRoot,
operatorSetIndex: operatorSetIndex,
proof: proof,
operatorSetLeafHash: keccak256(tableInfo)
operatorSetLeafHash: keccak256(operatorTableBytes)
});

// Update the operator table
if (curveType == CurveType.BN254) {
bn254CertificateVerifier.updateOperatorTable(
operatorSet, referenceTimestamp, _getBN254OperatorSetInfo(tableInfo), operatorSetConfig
operatorSet, referenceTimestamp, _getBN254OperatorSetInfo(operatorTableBytes), operatorSetConfig
);
} else if (curveType == CurveType.ECDSA) {
ecdsaCertificateVerifier.updateOperatorTable(
operatorSet, referenceTimestamp, _getECDSAOperatorSetInfo(tableInfo), operatorSetConfig
operatorSet, referenceTimestamp, _getECDSAOperatorSetInfo(operatorTableBytes), operatorSetConfig
);
} else {
revert InvalidCurveType();
Expand Down
Loading