From ba793b08b45d81f28f4ad1310408668c606664ce Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Tue, 26 Nov 2024 16:49:01 +0800 Subject: [PATCH] unfinished --- src/iBTC_NetworkMiddleware.sol | 74 ++++++++---------- test/iBTC_NetworkMiddleware.t.sol | 126 +++++++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 46 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index 71c48d2..3806df9 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -66,9 +66,7 @@ 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); } @@ -98,18 +96,32 @@ 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) { + return operators.contains(operator); + } + + 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) { + return vaults.contains(vault); + } + + function getVaultInfo(address vault) public view returns (uint48, uint48) { + (uint48 enabledTime, uint48 disabledTime) = vaults.getTimes(vault); + return (enabledTime, disabledTime); + } + function getCurrentEpoch() public view returns (uint48 epoch) { return getEpochAtTs(Time.timestamp()); } @@ -141,21 +153,15 @@ 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()) { @@ -165,9 +171,7 @@ 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(); } @@ -191,21 +195,15 @@ 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()) { @@ -237,18 +235,14 @@ 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()); @@ -315,9 +309,7 @@ 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) @@ -347,9 +339,7 @@ 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) diff --git a/test/iBTC_NetworkMiddleware.t.sol b/test/iBTC_NetworkMiddleware.t.sol index 5d3d034..54295ff 100644 --- a/test/iBTC_NetworkMiddleware.t.sol +++ b/test/iBTC_NetworkMiddleware.t.sol @@ -48,7 +48,7 @@ contract iBTC_NetworkMiddlewareTest is Test { VaultConfigurator public vaultConfigurator; iBTC_Vault public iBTC_vault; - function setup() public { + function setUp() public { address[] memory whitelistedDepositors; uint256 depositLimit = 1e10; // 100iBTC @@ -154,8 +154,126 @@ contract iBTC_NetworkMiddlewareTest is Test { } function testRegisterOperator() public { - for operator in operators{ - - } + vm.startPrank(OWNER); + + 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"); + + vm.stopPrank(); + } + + 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); // 模拟时间推进 + iBTC_middleware.unregisterOperator(operator); + + // 验证操作员已被移除 + bool isOperatorRegistered = iBTC_middleware.isOperatorRegistered(operator); + assertFalse(isOperatorRegistered, "Operator should be unregistered"); + + vm.stopPrank(); + } + + 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"); + + vm.stopPrank(); + } + + 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"); + + vm.stopPrank(); + } + + 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)); // 以合约身份操作缓存更新 + 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"); + + vm.stopPrank(); } }