Skip to content

Commit

Permalink
feat: add collateral whitelist logic
Browse files Browse the repository at this point in the history
  • Loading branch information
merklefruit committed Sep 6, 2024
1 parent ed15b05 commit fee14bd
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
1 change: 1 addition & 0 deletions bolt-contracts/script/DeployManager.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ contract DeployBoltManager is Script {
console.log("BoltValidators deployed at", address(validators));

BoltManager manager = new BoltManager(
address(sender),
address(validators),
symbioticNetwork,
symbioticOperatorRegistry,
Expand Down
21 changes: 15 additions & 6 deletions bolt-contracts/src/contracts/BoltManager.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Time} from "@openzeppelin/contracts/utils/types/Time.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
Expand All @@ -15,7 +16,7 @@ import {MapWithTimeData} from "../lib/MapWithTimeData.sol";
import {IBoltValidators} from "../interfaces/IBoltValidators.sol";
import {IBoltManager} from "../interfaces/IBoltManager.sol";

contract BoltManager is IBoltManager {
contract BoltManager is IBoltManager, Ownable {
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableMap for EnumerableMap.AddressToUintMap;
using MapWithTimeData for EnumerableMap.AddressToUintMap;
Expand Down Expand Up @@ -52,9 +53,6 @@ contract BoltManager is IBoltManager {
/// @notice Start timestamp of the first epoch.
uint48 public immutable START_TIMESTAMP;

/// @notice Address of the account that is authorized to set the collateral whitelist.
address public immutable COLLATERAL_WHITELIST_SETTER;

/// @notice Set of collateral addresses that are whitelisted.
EnumerableSet.AddressSet private whitelistedCollaterals;

Expand All @@ -65,12 +63,13 @@ contract BoltManager is IBoltManager {
/// @param _symbioticOperatorNetOptIn The address of the Symbiotic operator network opt-in contract.
/// @param _symbioticVaultRegistry The address of the Symbiotic vault registry.
constructor(
address _owner,
address _validators,
address _symbioticNetwork,
address _symbioticOperatorRegistry,
address _symbioticOperatorNetOptIn,
address _symbioticVaultRegistry
) {
) Ownable(_owner) {
validators = IBoltValidators(_validators);
START_TIMESTAMP = Time.timestamp();

Expand All @@ -95,6 +94,14 @@ contract BoltManager is IBoltManager {
return getEpochAtTs(Time.timestamp());
}

function addWhitelistedCollateral(address collateral) public onlyOwner {
whitelistedCollaterals.add(collateral);
}

function removeWhitelistedCollateral(address collateral) public onlyOwner {
whitelistedCollaterals.remove(collateral);
}

function getWhitelistedCollaterals() public view returns (address[] memory collaterals) {
return whitelistedCollaterals.values();
}
Expand Down Expand Up @@ -151,7 +158,9 @@ contract BoltManager is IBoltManager {
revert NotVault();
}

// TODO: check collateral asset against whitelist?
if (!isCollateralWhitelisted(IVault(vault).collateral())) {
revert CollateralNotWhitelisted();
}

// TODO: check slashing conditions and veto duration

Expand Down
1 change: 1 addition & 0 deletions bolt-contracts/src/interfaces/IBoltManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface IBoltManager {
error OperatorNotOptedIn();
error NotOperator();
error NotVault();
error CollateralNotWhitelisted();

function registerSymbioticOperator(address operator) external;

Expand Down
33 changes: 26 additions & 7 deletions bolt-contracts/test/BoltManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {IDelegatorFactory} from "@symbiotic/interfaces/IDelegatorFactory.sol";
import {IMigratablesFactory} from "@symbiotic/interfaces/common/IMigratablesFactory.sol";
import {Subnetwork} from "@symbiotic/contracts/libraries/Subnetwork.sol";

import {IBoltManager} from "../src/interfaces/IBoltManager.sol";
import {IBoltValidators} from "../src/interfaces/IBoltValidators.sol";
import {BoltValidators} from "../src/contracts/BoltValidators.sol";
import {BoltManager} from "../src/contracts/BoltManager.sol";
Expand Down Expand Up @@ -146,24 +147,27 @@ contract BoltManagerTest is Test {

validators = new BoltValidators(admin);
manager = new BoltManager(
admin,
address(validators),
networkAdmin,
address(operatorRegistry),
address(operatorNetworkOptInService),
address(vaultFactory)
);

// --- Whitelist collateral in BoltManager ---
vm.prank(admin);
manager.addWhitelistedCollateral(address(collateral));
}

/// @notice Internal helper to register Symbiotic contracts and opt-in operators and vaults.
/// Should be called inside other tests that need a common setup beyond the default setUp().
function _optInSymbioticRoutine() internal {
// --- Register Network in Symbiotic ---
function _symbioticOptInRoutine() internal {
// --- Register Network and Middleware in Symbiotic ---

vm.prank(networkAdmin);
networkRegistry.registerNetwork();

// --- Register Middleware in Symbiotic ---

vm.prank(networkAdmin);
networkMiddlewareService.setMiddleware(address(manager));

Expand Down Expand Up @@ -232,7 +236,7 @@ contract BoltManagerTest is Test {
}

function testReadOperatorStake() public {
_optInSymbioticRoutine();
_symbioticOptInRoutine();

// --- Read the operator stake ---

Expand Down Expand Up @@ -276,7 +280,7 @@ contract BoltManagerTest is Test {
}

function testGetProposerStatus() public {
_optInSymbioticRoutine();
_symbioticOptInRoutine();

BLS12381.G1Point memory pubkey = BLS12381.generatorG1();
bytes32 pubkeyHash = _pubkeyHash(pubkey);
Expand All @@ -295,11 +299,26 @@ contract BoltManagerTest is Test {
}

function testGetNonExistentProposerStatus() public {
_optInSymbioticRoutine();
_symbioticOptInRoutine();

bytes32 pubkeyHash = bytes32(uint256(1));

vm.expectRevert(IBoltValidators.ValidatorDoesNotExist.selector);
manager.getProposerStatus(pubkeyHash);
}

function testGetWhitelistedCollaterals() public {
address[] memory collaterals = manager.getWhitelistedCollaterals();
assertEq(collaterals.length, 1);
assertEq(collaterals[0], address(collateral));
}

function testNonWhitelistedCollateral() public {
vm.prank(admin);
manager.removeWhitelistedCollateral(address(collateral));

vm.prank(vaultAdmin);
vm.expectRevert(IBoltManager.CollateralNotWhitelisted.selector);
manager.registerSymbioticVault(address(vault));
}
}

0 comments on commit fee14bd

Please sign in to comment.