Skip to content

Commit

Permalink
still progressing
Browse files Browse the repository at this point in the history
  • Loading branch information
Rayerleier authored and scolear committed Nov 26, 2024
1 parent dfff923 commit 8930a86
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 61 deletions.
72 changes: 54 additions & 18 deletions src/iBTC_NetworkMiddleware.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
EnumerableMap.AddressToUintMap private operators;
EnumerableMap.AddressToUintMap private vaults;

modifier updateStakeCache(uint48 epoch) {
modifier updateStakeCache(
uint48 epoch
) {
if (!totalStakeCached[epoch]) {
calcAndCacheStakes(epoch);
}
Expand Down Expand Up @@ -96,28 +98,40 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
SLASHING_WINDOW = _slashingWindow;
}

function getEpochStartTs(uint48 epoch) public view returns (uint48 timestamp) {
function getEpochStartTs(
uint48 epoch
) public view returns (uint48 timestamp) {
return START_TIME + epoch * EPOCH_DURATION;
}

function getEpochAtTs(uint48 timestamp) public view returns (uint48 epoch) {
function getEpochAtTs(
uint48 timestamp
) public view returns (uint48 epoch) {
return (timestamp - START_TIME) / EPOCH_DURATION;
}

function isOperatorRegistered(address operator) public view returns (bool) {
function isOperatorRegistered(
address operator
) public view returns (bool) {
return operators.contains(operator);
}

function getOperatorInfo(address operator) public view returns (uint48, uint48) {
function getOperatorInfo(
address operator
) public view returns (uint48, uint48) {
(uint48 enabledTime, uint48 disabledTime) = operators.getTimes(operator);
return (enabledTime, disabledTime);
}

function isVaultRegistered(address vault) public view returns (bool) {
function isVaultRegistered(
address vault
) public view returns (bool) {
return vaults.contains(vault);
}

function getVaultInfo(address vault) public view returns (uint48, uint48) {
function getVaultInfo(
address vault
) public view returns (uint48, uint48) {
(uint48 enabledTime, uint48 disabledTime) = vaults.getTimes(vault);
return (enabledTime, disabledTime);
}
Expand Down Expand Up @@ -153,15 +167,21 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
updateKey(operator, key);
}

function pauseOperator(address operator) external onlyOwner {
function pauseOperator(
address operator
) external onlyOwner {
operators.disable(operator);
}

function unpauseOperator(address operator) external onlyOwner {
function unpauseOperator(
address operator
) external onlyOwner {
operators.enable(operator);
}

function unregisterOperator(address operator) external onlyOwner {
function unregisterOperator(
address operator
) external onlyOwner {
(, uint48 disabledTime) = operators.getTimes(operator);

if (disabledTime == 0 || disabledTime + SLASHING_WINDOW > Time.timestamp()) {
Expand All @@ -171,7 +191,9 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
operators.remove(operator);
}

function registerVault(address vault) external onlyOwner {
function registerVault(
address vault
) external onlyOwner {
if (vaults.contains(vault)) {
revert VaultAlreadyRegistred();
}
Expand All @@ -195,15 +217,21 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
vaults.enable(vault);
}

function pauseVault(address vault) external onlyOwner {
function pauseVault(
address vault
) external onlyOwner {
vaults.disable(vault);
}

function unpauseVault(address vault) external onlyOwner {
function unpauseVault(
address vault
) external onlyOwner {
vaults.enable(vault);
}

function unregisterVault(address vault) external onlyOwner {
function unregisterVault(
address vault
) external onlyOwner {
(, uint48 disabledTime) = vaults.getTimes(vault);

if (disabledTime == 0 || disabledTime + SLASHING_WINDOW > Time.timestamp()) {
Expand Down Expand Up @@ -235,14 +263,18 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
return stake;
}

function getTotalStake(uint48 epoch) public view returns (uint256) {
function getTotalStake(
uint48 epoch
) public view returns (uint256) {
if (totalStakeCached[epoch]) {
return totalStakeCache[epoch];
}
return _calcTotalStake(epoch);
}

function getValidatorSet(uint48 epoch) public view returns (ValidatorData[] memory validatorsData) {
function getValidatorSet(
uint48 epoch
) public view returns (ValidatorData[] memory validatorsData) {
uint48 epochStartTs = getEpochStartTs(epoch);

validatorsData = new ValidatorData[](operators.length());
Expand Down Expand Up @@ -309,7 +341,9 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
}
}

function calcAndCacheStakes(uint48 epoch) public returns (uint256 totalStake) {
function calcAndCacheStakes(
uint48 epoch
) public returns (uint256 totalStake) {
uint48 epochStartTs = getEpochStartTs(epoch);

// for epoch older than SLASHING_WINDOW total stake can be invalidated (use cache)
Expand Down Expand Up @@ -339,7 +373,9 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable {
totalStakeCache[epoch] = totalStake;
}

function _calcTotalStake(uint48 epoch) private view returns (uint256 totalStake) {
function _calcTotalStake(
uint48 epoch
) private view returns (uint256 totalStake) {
uint48 epochStartTs = getEpochStartTs(epoch);

// for epoch older than SLASHING_WINDOW total stake can be invalidated (use cache)
Expand Down
61 changes: 18 additions & 43 deletions test/iBTC_NetworkMiddleware.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,30 @@ import {IBaseDelegator} from "core/src/interfaces/delegator/IBaseDelegator.sol";
import {IVetoSlasher} from "core/src/interfaces/slasher/IVetoSlasher.sol";
import {IBaseSlasher} from "core/src/interfaces/slasher/IBaseSlasher.sol";
import {IVaultConfigurator} from "core/src/interfaces/IVaultConfigurator.sol";
import {IRegistry} from "core/src/interfaces/common/IRegistry.sol";

contract iBTC_NetworkMiddlewareTest is Test {
// sepolia
address constant NETWORKMIDDLEWARESERVICE = 0x62a1ddfD86b4c1636759d9286D3A0EC722D086e3;
address constant NETWORKREGISTRY = 0x7d03b7343BF8d5cEC7C0C27ecE084a20113D15C9;
address constant OPERATOR_REGISTRY = 0x6F75a4ffF97326A00e52662d82EA4FdE86a2C548;
address constant NETWORK_REGISTRY = 0x7d03b7343BF8d5cEC7C0C27ecE084a20113D15C9;
address constant NETWORK_OPTIN = 0x58973d16FFA900D11fC22e5e2B6840d9f7e13401;
address constant COLLATTERAL = 0xeb762Ed11a09E4A394C9c8101f8aeeaf5382ED74; // iBTC on sepolia
address constant COLLATTERAL = 0xeb762Ed11a09E4A394C9c8101f8aeeaf5382ED74;
address constant VAULT_FACTORY = 0x407A039D94948484D356eFB765b3c74382A050B4;
address constant DELEGATOR_FACTORY = 0x890CA3f95E0f40a79885B7400926544B2214B03f;
address constant SLASHER_FACTORY = 0xbf34bf75bb779c383267736c53a4ae86ac7bB299;
uint256 constant MAX_WITHDRAW_AMOUNT = 1e9; // 10 iBTC
uint256 constant MAX_WITHDRAW_AMOUNT = 1e9;
uint256 constant MIN_WITHDRAW_AMOUNT = 1e4;

// Using anvil's default addresses
address constant NETWORK = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; // first address
address constant OWNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; // second address
address constant NETWORK = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address constant OWNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;
uint48 constant EPOCH_DURATION = 7 days;
uint48 constant SLASHING_WINDOW = 8 days;
uint48 constant SLASHING_WINDOW = 7 days;
uint48 vetoDuration = 0 days;

// Initial operators and their keys (if any)
address[] operators;
bytes32[] keys;

// Initial vaults (if any)
address[] vaults;

NetworkMiddleware public iBTC_middleware;
Expand All @@ -51,14 +49,13 @@ contract iBTC_NetworkMiddlewareTest is Test {
function setUp() public {
address[] memory whitelistedDepositors;

uint256 depositLimit = 1e10; // 100iBTC
uint256 depositLimit = 1e10;
address hook = 0x0000000000000000000000000000000000000000;
uint64 delegatorIndex = 0; // NetworkRestakeDelegator
uint64 slasherIndex = 1; // vetoSlasher
uint64 delegatorIndex = 0;
uint64 slasherIndex = 1;
bool withSlasher = true;
uint48 vetoDuration = 86_400; // 1 day
vm.startPrank(OWNER);
// iBTC_vault deployment Starts

vaultConfigurator = new VaultConfigurator(VAULT_FACTORY, DELEGATOR_FACTORY, SLASHER_FACTORY);
burner = new BurnerRouter();
(,, address deployer) = vm.readCallers();
Expand Down Expand Up @@ -88,7 +85,6 @@ contract iBTC_NetworkMiddlewareTest is Test {
operatorNetworkLimitSetRoleHolders[0] = OWNER;
operatorNetworkSharesSetRoleHolders[0] = OWNER;
bytes memory delegatorParams;
// delegator = 0,NetworkRestakeDelegator
delegatorParams = abi.encode(
INetworkRestakeDelegator.InitParams({
baseParams: IBaseDelegator.BaseParams({defaultAdminRoleHolder: OWNER, hook: hook, hookSetRoleHolder: OWNER}),
Expand All @@ -97,7 +93,6 @@ contract iBTC_NetworkMiddlewareTest is Test {
})
);
bytes memory slasherParams;
// slasherIndex =1, VetoSlash
slasherParams = abi.encode(
IVetoSlasher.InitParams({
baseParams: IBaseSlasher.BaseParams({isBurnerHook: address(burner) != address(0)}),
Expand Down Expand Up @@ -129,9 +124,13 @@ contract iBTC_NetworkMiddlewareTest is Test {
iBTC_Vault(vault_).renounceRole(iBTC_Vault(vault_).DEPOSITOR_WHITELIST_ROLE(), deployer);
iBTC_Vault(vault_).renounceRole(iBTC_Vault(vault_).DEFAULT_ADMIN_ROLE(), deployer);
}
// vault delpoymend ends
vm.stopPrank();

vm.startPrank(vault_);
NetworkRegistry(NETWORK_REGISTRY).registerNetwork();
vm.stopPrank();
vaults.push(vault_);
vm.startPrank(OWNER);
iBTC_middleware = new NetworkMiddleware(
NETWORK, OPERATOR_REGISTRY, NETWORK_REGISTRY, NETWORK_OPTIN, OWNER, EPOCH_DURATION, SLASHING_WINDOW
);
Expand Down Expand Up @@ -159,13 +158,10 @@ contract iBTC_NetworkMiddlewareTest is Test {
address operator = address(0x1234);
bytes32 key = keccak256(abi.encodePacked("operator_key"));

// 注册操作员
iBTC_middleware.registerOperator(operator, key);

// 获取启用时间和禁用时间
(uint48 enabledTime, uint48 disabledTime) = iBTC_middleware.getOperatorInfo(operator);

// 验证操作员已经注册
assertTrue(enabledTime > 0, "Enabled time should be greater than 0");
assertTrue(disabledTime == 0, "Disabled time should be 0");

Expand All @@ -175,21 +171,16 @@ contract iBTC_NetworkMiddlewareTest is Test {
function testUnregisterOperator() public {
vm.startPrank(OWNER);

// 假设有一个操作员
address operator = address(0x1234);
bytes32 key = keccak256(abi.encodePacked("operator_key"));

// 注册操作员
iBTC_middleware.registerOperator(operator, key);

// 暂停操作员
iBTC_middleware.pauseOperator(operator);

// 尝试取消注册操作员
vm.warp(block.timestamp + SLASHING_WINDOW + 1); // 模拟时间推进
vm.warp(block.timestamp + SLASHING_WINDOW + 1);
iBTC_middleware.unregisterOperator(operator);

// 验证操作员已被移除
bool isOperatorRegistered = iBTC_middleware.isOperatorRegistered(operator);
assertFalse(isOperatorRegistered, "Operator should be unregistered");

Expand All @@ -199,13 +190,10 @@ contract iBTC_NetworkMiddlewareTest is Test {
function testRegisterVault() public {
vm.startPrank(OWNER);

// 假设有一个Vault地址
address vault = address(0x7890);

// 注册Vault
iBTC_middleware.registerVault(vault);

// 验证Vault已经注册
bool isVaultRegistered = iBTC_middleware.isVaultRegistered(vault);
assertTrue(isVaultRegistered, "Vault should be registered");

Expand All @@ -215,25 +203,19 @@ contract iBTC_NetworkMiddlewareTest is Test {
function testPauseAndUnpauseVault() public {
vm.startPrank(OWNER);

// 假设有一个Vault地址
address vault = address(0x7890);

// 注册Vault
iBTC_middleware.registerVault(vault);

// 暂停Vault
iBTC_middleware.pauseVault(vault);

// 验证Vault已暂停
(uint48 enabledTime, uint48 disabledTime) = iBTC_middleware.getVaultInfo(vault);
bool isVaultPaused = enabledTime == 0 || (disabledTime > 0 && disabledTime <= block.timestamp);

assertTrue(isVaultPaused, "Vault should be paused");

// 恢复Vault
iBTC_middleware.unpauseVault(vault);

// 验证Vault已恢复
(enabledTime, disabledTime) = iBTC_middleware.getVaultInfo(vault);
isVaultPaused = enabledTime == 0 || (disabledTime > 0 && disabledTime <= block.timestamp);
assertFalse(isVaultPaused, "Vault should be active");
Expand All @@ -244,33 +226,26 @@ contract iBTC_NetworkMiddlewareTest is Test {
function testSlashOperator() public {
vm.startPrank(OWNER);

// 假设有一个操作员和一个Vault
address operator = address(0x1234);
bytes32 key = keccak256(abi.encodePacked("operator_key"));
address vault = address(0x7890);

// 注册操作员和Vault
iBTC_middleware.registerOperator(operator, key);
iBTC_middleware.registerVault(vault);

// 假设某个epoch中stake为1000
uint48 epoch = iBTC_middleware.getCurrentEpoch();
uint256 initialStake = 1000;

// 模拟缓存 Stake 值,通过合约方法完成
vm.startPrank(address(iBTC_middleware)); // 以合约身份操作缓存更新
vm.startPrank(address(iBTC_middleware));
iBTC_middleware.calcAndCacheStakes(epoch);
vm.stopPrank();

// 查询缓存的Stake值
uint256 cachedStake = iBTC_middleware.operatorStakeCache(epoch, operator);
assertEq(cachedStake, initialStake, "Cached stake should match the initial stake");

// Slash 操作员 100
uint256 slashAmount = 100;
iBTC_middleware.slash(epoch, operator, slashAmount);

// 验证 Stake 减少了
uint256 updatedStake = iBTC_middleware.getOperatorStake(operator, epoch);
assertEq(updatedStake, initialStake - slashAmount, "Stake should be reduced by slashed amount");

Expand Down

0 comments on commit 8930a86

Please sign in to comment.