From 6222fe8be779d17102f53fe3844291e458e312a3 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 5 Dec 2024 16:11:04 +0800 Subject: [PATCH 1/6] clean up --- src/iBTC_NetworkMiddleware.sol | 56 +++++++++------------------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index e53ea43..f06f605 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -72,9 +72,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); } @@ -109,15 +107,11 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable { subnetworksCnt = 1; } - 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; } @@ -177,21 +171,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()) { @@ -201,9 +189,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(); } @@ -227,21 +213,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()) { @@ -286,18 +266,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()); @@ -364,9 +340,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) @@ -396,9 +370,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) From f73b35a9d5047393d7b2ba05f8a82594edd82b8e Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 5 Dec 2024 20:08:20 +0800 Subject: [PATCH 2/6] pass checked --- src/iBTC_NetworkMiddleware.sol | 58 ++++++-- test/iBTC_NetworkMiddleware.t.sol | 225 +++++++++--------------------- 2 files changed, 111 insertions(+), 172 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index f06f605..c8780b6 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -72,7 +72,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); } @@ -107,11 +109,15 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable { subnetworksCnt = 1; } - 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; } @@ -171,15 +177,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()) { @@ -189,7 +201,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(); } @@ -213,15 +227,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()) { @@ -266,14 +286,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()); @@ -325,7 +349,7 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable { // simple pro-rata slasher for (uint256 i; i < vaults.length(); ++i) { - (address vault, uint48 enabledTime, uint48 disabledTime) = operators.atWithTimes(i); + (address vault, uint48 enabledTime, uint48 disabledTime) = vaults.atWithTimes(i); // just skip the vault if it was enabled after the target epoch or not enabled if (!_wasActiveAt(enabledTime, disabledTime, epochStartTs)) { @@ -340,7 +364,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) @@ -370,7 +396,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) diff --git a/test/iBTC_NetworkMiddleware.t.sol b/test/iBTC_NetworkMiddleware.t.sol index 3e18e86..10be8dd 100644 --- a/test/iBTC_NetworkMiddleware.t.sol +++ b/test/iBTC_NetworkMiddleware.t.sol @@ -17,6 +17,9 @@ import {MetadataService} from "core/test/service/MetadataService.t.sol"; import {BaseDelegatorHints} from "lib/burners/lib/core/src/contracts/hints/DelegatorHints.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {MapWithTimeData} from "../src/libraries/MapWithTimeData.sol"; +import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; import {IVault} from "core/src/interfaces/vault/IVault.sol"; @@ -32,6 +35,8 @@ contract iBTC_NetworkMiddlewareTest is Test { using Math for uint256; using Subnetwork for bytes32; using Subnetwork for address; + using EnumerableMap for EnumerableMap.AddressToUintMap; + using MapWithTimeData for EnumerableMap.AddressToUintMap; uint256 sepoliaFork; string SEPOLIA_RPC_URL = vm.envString("SEPOLIA_RPC_URL"); @@ -49,6 +54,9 @@ contract iBTC_NetworkMiddlewareTest is Test { uint256 constant MAX_WITHDRAW_AMOUNT = 1e9; uint256 constant MIN_WITHDRAW_AMOUNT = 1e4; + bytes32 public constant NETWORK_LIMIT_SET_ROLE = keccak256("NETWORK_LIMIT_SET_ROLE"); + bytes32 public constant OPERATOR_NETWORK_SHARES_SET_ROLE = keccak256("OPERATOR_NETWORK_SHARES_SET_ROLE"); + address constant NETWORK = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; // first address network should be a multisig contract address constant OWNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; // second address uint48 constant EPOCH_DURATION = 7 days; @@ -56,7 +64,8 @@ contract iBTC_NetworkMiddlewareTest is Test { uint48 constant SLASHING_WINDOW = 7 days; uint48 vetoDuration = 0 days; - address[] operators; + EnumerableMap.AddressToUintMap operators; + bytes32[] keys; address[] vaults; @@ -96,7 +105,7 @@ contract iBTC_NetworkMiddlewareTest is Test { uint256 depositLimit = 1e10; address hook = 0x0000000000000000000000000000000000000000; uint64 delegatorIndex = 0; - uint64 slasherIndex = 1; + uint64 slasherIndex = 0; bool withSlasher = true; vm.startPrank(OWNER); @@ -271,183 +280,85 @@ contract iBTC_NetworkMiddlewareTest is Test { vm.stopPrank(); } - function testSlashOperator() public { - uint256 depositAmount = 1e10; - uint256 withdrawAmount = 1e9; - uint256 blockTimestamp = block.timestamp * block.timestamp / block.timestamp * block.timestamp / block.timestamp; - blockTimestamp = blockTimestamp + 1_720_700_948; - address operator = address(0x1234); - uint256 networkLimit = 1e10; - uint256 operatorNetworkShares1 = 1e10; - uint256 operatorNetworkShares2 = 5e9; - uint256 operatorNetworkShares3 = 1e9; + // function testSlashOperator() public { + // bytes32 key = keccak256(abi.encodePacked("alice_key")); - _setMaxNetworkLimit(NETWORK, 0, networkLimit); - _registerOperator(alice); - _registerOperator(bob); + // uint256 depositAmount = 1e10; + // uint256 blockTimestamp = block.timestamp * block.timestamp / block.timestamp * block.timestamp / block.timestamp; + // blockTimestamp = blockTimestamp + 1_720_700_948; + // uint256 networkLimit = 1e10; + // uint256 operatorNetworkShares1 = 1e10; + // vm.prank(OWNER); + // iBTC_networkMiddleware.registerVault(address(iBTC_vault)); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), bob), 0); + // assertEq(iBTC_vault.delegator(), address(iBTC_delegator), "delegator should be right."); + // _setMaxNetworkLimit(NETWORK, 0, networkLimit * 100); + // _registerOperator(alice); - _optInOperatorVault(alice); - _optInOperatorVault(bob); + // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), bob), 0); + // _optInOperatorVault(alice); - _optInOperatorNetwork(alice, NETWORK); - _optInOperatorNetwork(bob, NETWORK); + // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), bob), 0); + // _optInOperatorNetwork(alice, NETWORK); - _deposit(alice, depositAmount); - _withdraw(alice, withdrawAmount); + // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); + // vm.prank(OWNER); + // iBTC_networkMiddleware.registerOperator(alice, key); + // _deposit(alice, depositAmount); + // // _withdraw(alice, withdrawAmount); + // assertEq( + // depositAmount, iBTC_vault.activeBalanceOfAt(alice, uint48(block.timestamp), ""), "Deposit should be done" + // ); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), bob), 0); + // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - _setNetworkLimit(alice, NETWORK, networkLimit); + // vm.prank(OWNER); + // iBTC_delegator.grantRole(NETWORK_LIMIT_SET_ROLE, alice); + // _setNetworkLimit(alice, NETWORK, networkLimit); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), bob), 0); + // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - _setOperatorNetworkShares(alice, NETWORK, alice, operatorNetworkShares1); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), alice), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 - ) - ); - assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), bob), 0); - - _setOperatorNetworkShares(alice, NETWORK, bob, operatorNetworkShares2); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), alice), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 + operatorNetworkShares2 - ) - ); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), bob), - operatorNetworkShares2.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 + operatorNetworkShares2 - ) - ); + // vm.prank(OWNER); + // iBTC_delegator.grantRole(OPERATOR_NETWORK_SHARES_SET_ROLE, alice); + // _setOperatorNetworkShares(alice, NETWORK, alice, operatorNetworkShares1); + // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), operatorNetworkShares1); - _setOperatorNetworkShares(alice, NETWORK, bob, operatorNetworkShares2 - 1e9); - assertEq( - iBTC_delegator.stakeAt(NETWORK.subnetwork(0), alice, uint48(blockTimestamp), ""), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), - operatorNetworkShares1 + operatorNetworkShares2 - 1 - ) - ); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), alice), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), - operatorNetworkShares1 + operatorNetworkShares2 - 1 - ) - ); - assertEq( - iBTC_delegator.stakeAt(NETWORK.subnetwork(0), bob, uint48(blockTimestamp), ""), - (operatorNetworkShares2 - 1).mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), - operatorNetworkShares1 + operatorNetworkShares2 - 1 - ) - ); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), bob), - (operatorNetworkShares2 - 1).mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), - operatorNetworkShares1 + operatorNetworkShares2 - 1 - ) - ); + // (uint48 enabledTime, uint48 disabledTime) = iBTC_networkMiddleware.getOperatorInfo(alice); + // console.log("enabledTime", enabledTime); + // console.log("disabledTime", disabledTime); + // uint256 stakeAt = iBTC_delegator.stakeAt(NETWORK.subnetwork(0), alice, uint48(enabledTime), ""); + // assertEq(stakeAt, operatorNetworkShares1, "StakeAt should stand the same"); - blockTimestamp = blockTimestamp + 1 days; - vm.warp(blockTimestamp); + // uint48 epoch = iBTC_networkMiddleware.getCurrentEpoch(); + // assertEq( + // iBTC_networkMiddleware.getOperatorStake(alice, epoch), + // iBTC_delegator.stake(NETWORK.subnetwork(0), alice), + // "stake should same" + // ); - _setOperatorNetworkShares(alice, NETWORK, bob, operatorNetworkShares3); + // uint256 cachedStake = iBTC_networkMiddleware.calcAndCacheStakes(epoch); + // assertEq(cachedStake, operatorNetworkShares1, "cache should update"); + // uint256 slashAmount = 1e9; + // // vm.warp(1 days); + // uint48 epochStartTs = iBTC_networkMiddleware.getEpochStartTs(epoch); + // console.log("epochStartTs", epochStartTs); + // assertGe(epochStartTs, Time.timestamp()-iBTC_vault.epochDuration()); - assertEq( - iBTC_delegator.stakeAt(NETWORK.subnetwork(0), alice, uint48(blockTimestamp - 1), ""), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), - operatorNetworkShares1 + operatorNetworkShares2 - 1 - ) - ); - assertEq( - iBTC_delegator.stakeAt(NETWORK.subnetwork(0), alice, uint48(blockTimestamp), ""), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 + operatorNetworkShares3 - ) - ); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), alice), - operatorNetworkShares1.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 + operatorNetworkShares3 - ) - ); - assertEq( - iBTC_delegator.stakeAt(NETWORK.subnetwork(0), bob, uint48(blockTimestamp - 1), ""), - (operatorNetworkShares2 - 1).mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), - operatorNetworkShares1 + operatorNetworkShares2 - 1 - ) - ); - assertEq( - iBTC_delegator.stakeAt(NETWORK.subnetwork(0), bob, uint48(blockTimestamp), ""), - operatorNetworkShares3.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 + operatorNetworkShares3 - ) - ); - assertEq( - iBTC_delegator.stake(NETWORK.subnetwork(0), bob), - operatorNetworkShares3.mulDiv( - Math.min(depositAmount - withdrawAmount, networkLimit), operatorNetworkShares1 + operatorNetworkShares3 - ) - ); + // vm.prank(OWNER); + // iBTC_networkMiddleware.slash(epoch, alice, slashAmount); + // assertEq(cachedStake, depositAmount - slashAmount, "Cached stake should be reduced by slash amount"); - vm.startPrank(OWNER); - iBTC_networkMiddleware.registerVault(address(iBTC_vault)); - - vm.stopPrank(); - - uint48 epoch = iBTC_networkMiddleware.getCurrentEpoch(); - - vm.prank(operator); - iBTC_Vault(iBTC_vault).deposit(operator, depositAmount); - - assertEq( - depositAmount, - iBTC_Vault(iBTC_vault).activeBalanceOfAt(operator, uint48(block.timestamp), ""), - "Initial staking should be done" - ); - // OptIn vault, Network is already optIn - - vm.prank(address(iBTC_networkMiddleware)); - iBTC_networkMiddleware.calcAndCacheStakes(epoch); - - uint256 cachedStake = iBTC_networkMiddleware.operatorStakeCache(epoch, operator); - assertEq(cachedStake, depositAmount, "Cached stake should match the initial stake"); - - uint256 slashAmount = 100; - - vm.startPrank(OWNER); - iBTC_networkMiddleware.slash(epoch, operator, slashAmount); - - cachedStake = iBTC_networkMiddleware.operatorStakeCache(epoch, operator); - assertEq(cachedStake, depositAmount - slashAmount, "Cached stake should be reduced by slash amount"); - - vm.stopPrank(); - } + // vm.stopPrank(); + // } function testOptInVault() public { testRegisterOperator(); address operator = address(0x1234); vm.prank(operator); vault_optIn_service.optIn(address(iBTC_vault)); + assertTrue(vault_optIn_service.isOptedIn(operator, address(iBTC_vault))); } function _setMaxNetworkLimit(address user, uint96 identifier, uint256 amount) internal { From bc8de45d0dd5072a5a299789a47b4e3443ee5268 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Thu, 5 Dec 2024 21:25:41 +0800 Subject: [PATCH 3/6] finish test of slashing process --- script/Deploy_All.s.sol | 19 +++- test/iBTC_NetworkMiddleware.t.sol | 171 +++++++++++++++++------------- 2 files changed, 114 insertions(+), 76 deletions(-) diff --git a/script/Deploy_All.s.sol b/script/Deploy_All.s.sol index c6272a3..ec269a5 100644 --- a/script/Deploy_All.s.sol +++ b/script/Deploy_All.s.sol @@ -15,6 +15,8 @@ import {IBaseSlasher} from "@symbiotic/interfaces/slasher/IBaseSlasher.sol"; import {ISlasher} from "@symbiotic/interfaces/slasher/ISlasher.sol"; import {IVetoSlasher} from "@symbiotic/interfaces/slasher/IVetoSlasher.sol"; import {BurnerRouter} from "burners/src/contracts/router/BurnerRouter.sol"; +import {BurnerRouterFactory} from "burners/src/contracts/router/BurnerRouterFactory.sol"; +import {IBurnerRouter} from "burners/src/interfaces/router/IBurnerRouter.sol"; import {VaultConfigurator} from "../src/iBTC_VaultConfigurator.sol"; import {iBTC_Vault} from "../src/iBTC_Vault.sol"; @@ -24,7 +26,7 @@ contract DeployAll is Script { address constant COLLATERAL_ADDRESS = 0xeb762Ed11a09E4A394C9c8101f8aeeaf5382ED74; // eth sepolia uint256 constant MAX_WITHDRAW_AMOUNT = 1e9; // 10 iBTC uint256 constant MIN_WITHDRAW_AMOUNT = 1e4; - uint256 deployerPrivateKey = uint256(0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); //NOTE + address constant GLOABAL_RECEIVER = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; //NOTE third address // Replace with the correct checksummed addresses address constant VAULT_FACTORY = 0x407A039D94948484D356eFB765b3c74382A050B4; // Replace with deployed VaultFactory address @@ -44,7 +46,20 @@ contract DeployAll is Script { uint48 vetoDuration = 86_400; // 1 day vm.startBroadcast(); - BurnerRouter burner = new BurnerRouter(); + IBurnerRouter.NetworkReceiver[] memory networkReceiver; + IBurnerRouter.OperatorNetworkReceiver[] memory operatorNetworkReceiver; + IBurnerRouter.InitParams memory params = IBurnerRouter.InitParams({ + owner: owner, + collateral: collateral, + delay: 0, //NOTE we can set a delay + globalReceiver: GLOABAL_RECEIVER, + networkReceivers: networkReceiver, + operatorNetworkReceivers: operatorNetworkReceiver + }); + BurnerRouter burnerTemplate = new BurnerRouter(); + BurnerRouterFactory burnerRouterFactory = new BurnerRouterFactory(address(burnerTemplate)); + address burnerAddress = address(burnerRouterFactory.create(params)); + BurnerRouter burner = BurnerRouter(burnerAddress); // Deploy the iBTC_Burner contract VaultConfigurator vaultConfigurator = new VaultConfigurator(VAULT_FACTORY, DELEGATOR_FACTORY, SLASHER_FACTORY); diff --git a/test/iBTC_NetworkMiddleware.t.sol b/test/iBTC_NetworkMiddleware.t.sol index 10be8dd..0010f58 100644 --- a/test/iBTC_NetworkMiddleware.t.sol +++ b/test/iBTC_NetworkMiddleware.t.sol @@ -13,6 +13,7 @@ import {iBTC_Vault} from "src/iBTC_Vault.sol"; import {Subnetwork} from "core/src/contracts/libraries/Subnetwork.sol"; import {VaultConfigurator} from "src/iBTC_VaultConfigurator.sol"; import {BurnerRouter} from "burners/src/contracts/router/BurnerRouter.sol"; +import {BurnerRouterFactory} from "burners/src/contracts/router/BurnerRouterFactory.sol"; import {MetadataService} from "core/test/service/MetadataService.t.sol"; import {BaseDelegatorHints} from "lib/burners/lib/core/src/contracts/hints/DelegatorHints.sol"; @@ -22,7 +23,7 @@ import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; import {IVault} from "core/src/interfaces/vault/IVault.sol"; - +import {IBurnerRouter} from "burners/src/interfaces/router/IBurnerRouter.sol"; import {INetworkRestakeDelegator} from "core/src/interfaces/delegator/INetworkRestakeDelegator.sol"; import {IBaseDelegator} from "core/src/interfaces/delegator/IBaseDelegator.sol"; import {IVetoSlasher} from "core/src/interfaces/slasher/IVetoSlasher.sol"; @@ -59,6 +60,8 @@ contract iBTC_NetworkMiddlewareTest is Test { address constant NETWORK = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; // first address network should be a multisig contract address constant OWNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; // second address + address constant GLOABAL_RECEIVER = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; //NOTE third address + uint48 constant EPOCH_DURATION = 7 days; // uint48 constant NETWORK_EPOCH = 5 days; uint48 constant SLASHING_WINDOW = 7 days; @@ -110,7 +113,22 @@ contract iBTC_NetworkMiddlewareTest is Test { vm.startPrank(OWNER); vaultConfigurator = new VaultConfigurator(VAULT_FACTORY, DELEGATOR_FACTORY, SLASHER_FACTORY); - burner = new BurnerRouter(); + + IBurnerRouter.NetworkReceiver[] memory networkReceiver; + IBurnerRouter.OperatorNetworkReceiver[] memory operatorNetworkReceiver; + IBurnerRouter.InitParams memory params = IBurnerRouter.InitParams({ + owner: OWNER, + collateral: COLLATTERAL, + delay: 0, //NOTE we can set a delay + globalReceiver: GLOABAL_RECEIVER, + networkReceivers: networkReceiver, + operatorNetworkReceivers: operatorNetworkReceiver + }); + BurnerRouter burnerTemplate = new BurnerRouter(); + BurnerRouterFactory burnerRouterFactory = new BurnerRouterFactory(address(burnerTemplate)); + address burnerAddress = address(burnerRouterFactory.create(params)); + burner = BurnerRouter(burnerAddress); + assertEq(burner.collateral(), COLLATTERAL, "Burner Router should be setting correctly"); (,, address deployer) = vm.readCallers(); bool depositWhitelist = whitelistedDepositors.length != 0; @@ -280,78 +298,83 @@ contract iBTC_NetworkMiddlewareTest is Test { vm.stopPrank(); } - // function testSlashOperator() public { - // bytes32 key = keccak256(abi.encodePacked("alice_key")); - - // uint256 depositAmount = 1e10; - // uint256 blockTimestamp = block.timestamp * block.timestamp / block.timestamp * block.timestamp / block.timestamp; - // blockTimestamp = blockTimestamp + 1_720_700_948; - // uint256 networkLimit = 1e10; - // uint256 operatorNetworkShares1 = 1e10; - // vm.prank(OWNER); - // iBTC_networkMiddleware.registerVault(address(iBTC_vault)); - - // assertEq(iBTC_vault.delegator(), address(iBTC_delegator), "delegator should be right."); - // _setMaxNetworkLimit(NETWORK, 0, networkLimit * 100); - // _registerOperator(alice); - - // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - - // _optInOperatorVault(alice); - - // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - - // _optInOperatorNetwork(alice, NETWORK); - - // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - // vm.prank(OWNER); - // iBTC_networkMiddleware.registerOperator(alice, key); - // _deposit(alice, depositAmount); - // // _withdraw(alice, withdrawAmount); - // assertEq( - // depositAmount, iBTC_vault.activeBalanceOfAt(alice, uint48(block.timestamp), ""), "Deposit should be done" - // ); - - // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - - // vm.prank(OWNER); - // iBTC_delegator.grantRole(NETWORK_LIMIT_SET_ROLE, alice); - // _setNetworkLimit(alice, NETWORK, networkLimit); - - // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); - - // vm.prank(OWNER); - // iBTC_delegator.grantRole(OPERATOR_NETWORK_SHARES_SET_ROLE, alice); - // _setOperatorNetworkShares(alice, NETWORK, alice, operatorNetworkShares1); - // assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), operatorNetworkShares1); - - // (uint48 enabledTime, uint48 disabledTime) = iBTC_networkMiddleware.getOperatorInfo(alice); - // console.log("enabledTime", enabledTime); - // console.log("disabledTime", disabledTime); - // uint256 stakeAt = iBTC_delegator.stakeAt(NETWORK.subnetwork(0), alice, uint48(enabledTime), ""); - // assertEq(stakeAt, operatorNetworkShares1, "StakeAt should stand the same"); - - // uint48 epoch = iBTC_networkMiddleware.getCurrentEpoch(); - // assertEq( - // iBTC_networkMiddleware.getOperatorStake(alice, epoch), - // iBTC_delegator.stake(NETWORK.subnetwork(0), alice), - // "stake should same" - // ); - - // uint256 cachedStake = iBTC_networkMiddleware.calcAndCacheStakes(epoch); - // assertEq(cachedStake, operatorNetworkShares1, "cache should update"); - // uint256 slashAmount = 1e9; - // // vm.warp(1 days); - // uint48 epochStartTs = iBTC_networkMiddleware.getEpochStartTs(epoch); - // console.log("epochStartTs", epochStartTs); - // assertGe(epochStartTs, Time.timestamp()-iBTC_vault.epochDuration()); - - // vm.prank(OWNER); - // iBTC_networkMiddleware.slash(epoch, alice, slashAmount); - // assertEq(cachedStake, depositAmount - slashAmount, "Cached stake should be reduced by slash amount"); - - // vm.stopPrank(); - // } + function testSlashOperator() public { + bytes32 key = keccak256(abi.encodePacked("alice_key")); + + uint256 depositAmount = 1e10; + uint256 blockTimestamp = block.timestamp * block.timestamp / block.timestamp * block.timestamp / block.timestamp; + blockTimestamp = blockTimestamp + 1_720_700_948; + uint256 networkLimit = 1e10; + uint256 operatorNetworkShares1 = 1e10; + vm.prank(OWNER); + iBTC_networkMiddleware.registerVault(address(iBTC_vault)); + + assertEq(iBTC_vault.delegator(), address(iBTC_delegator), "delegator should be right."); + _setMaxNetworkLimit(NETWORK, 0, networkLimit * 100); + _registerOperator(alice); + + assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); + + _optInOperatorVault(alice); + + assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); + + _optInOperatorNetwork(alice, NETWORK); + + assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); + vm.prank(OWNER); + iBTC_networkMiddleware.registerOperator(alice, key); + _deposit(alice, depositAmount); + // _withdraw(alice, withdrawAmount); + assertEq( + depositAmount, iBTC_vault.activeBalanceOfAt(alice, uint48(block.timestamp), ""), "Deposit should be done" + ); + + assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); + + vm.prank(OWNER); + iBTC_delegator.grantRole(NETWORK_LIMIT_SET_ROLE, alice); + _setNetworkLimit(alice, NETWORK, networkLimit); + + assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), 0); + + vm.prank(OWNER); + iBTC_delegator.grantRole(OPERATOR_NETWORK_SHARES_SET_ROLE, alice); + _setOperatorNetworkShares(alice, NETWORK, alice, operatorNetworkShares1); + assertEq(iBTC_delegator.stake(NETWORK.subnetwork(0), alice), operatorNetworkShares1); + + (uint48 enabledTime, uint48 disabledTime) = iBTC_networkMiddleware.getOperatorInfo(alice); + console.log("enabledTime", enabledTime); + console.log("disabledTime", disabledTime); + uint256 stakeAt = iBTC_delegator.stakeAt(NETWORK.subnetwork(0), alice, uint48(enabledTime), ""); + assertEq(stakeAt, operatorNetworkShares1, "StakeAt should stand the same"); + + uint48 epoch = iBTC_networkMiddleware.getCurrentEpoch(); + assertEq( + iBTC_networkMiddleware.getOperatorStake(alice, epoch), + iBTC_delegator.stake(NETWORK.subnetwork(0), alice), + "stake should same" + ); + + uint256 cachedStake = iBTC_networkMiddleware.calcAndCacheStakes(epoch); + assertEq(cachedStake, operatorNetworkShares1, "cache should update"); + uint256 slashAmount = 1e9; + vm.warp(Time.timestamp() + 1 days); + uint48 epochStartTs = iBTC_networkMiddleware.getEpochStartTs(epoch); + assertGe( + epochStartTs, + Time.timestamp() - iBTC_vault.epochDuration(), + "captureTimesstamp needs greater and equal that Time.timestamp()-iBTC_vault.epochDuration()" + ); + assertLt(epochStartTs, Time.timestamp(), "captureTimestamp needs less than Time.timestamp();"); + + vm.prank(OWNER); + iBTC_networkMiddleware.slash(epoch, alice, slashAmount); + uint256 amountAfterSlashed = iBTC_vault.activeBalanceOf(alice); + assertEq(amountAfterSlashed, depositAmount - slashAmount, "Cached stake should be reduced by slash amount"); + + vm.stopPrank(); + } function testOptInVault() public { testRegisterOperator(); From 5aabc98fb27f91a8f3767fbc799ea6b119390ca5 Mon Sep 17 00:00:00 2001 From: scolear Date: Thu, 5 Dec 2024 15:11:33 +0100 Subject: [PATCH 4/6] chore: update ghwf file --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 762a296..4cc98eb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,6 +7,7 @@ on: env: FOUNDRY_PROFILE: ci + SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }} jobs: check: From ded4a8e513fb29f5cdd743ac20099199d2810e15 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Fri, 6 Dec 2024 17:05:42 +0800 Subject: [PATCH 5/6] deleted a unused parameter --- src/iBTC_NetworkMiddleware.sol | 1 - test/iBTC_NetworkMiddleware.t.sol | 1 - 2 files changed, 2 deletions(-) diff --git a/src/iBTC_NetworkMiddleware.sol b/src/iBTC_NetworkMiddleware.sol index c8780b6..a290e28 100644 --- a/src/iBTC_NetworkMiddleware.sol +++ b/src/iBTC_NetworkMiddleware.sol @@ -87,7 +87,6 @@ contract NetworkMiddleware is SimpleKeyRegistry32, Ownable { address _networkRegistry, address _vaultRegistry, address _operatorNetOptin, - address _operatorVaultOptin, address _owner, uint48 _epochDuration, uint48 _slashingWindow diff --git a/test/iBTC_NetworkMiddleware.t.sol b/test/iBTC_NetworkMiddleware.t.sol index 0010f58..94a19c3 100644 --- a/test/iBTC_NetworkMiddleware.t.sol +++ b/test/iBTC_NetworkMiddleware.t.sol @@ -212,7 +212,6 @@ contract iBTC_NetworkMiddlewareTest is Test { NETWORK_REGISTRY, VAULT_FACTORY, NEWTORK_OPTIN_SERVICE, - VAULT_OPTIN_SERVICE, OWNER, EPOCH_DURATION, SLASHING_WINDOW From 9f824f2cfd7199a9a247c6ffa4fe84ed2d6215f4 Mon Sep 17 00:00:00 2001 From: Rayerleier <1045643889@qq.com> Date: Fri, 6 Dec 2024 20:52:53 +0800 Subject: [PATCH 6/6] fixed: some spell --- script/Deploy_All.s.sol | 4 ++-- test/iBTC_NetworkMiddleware.t.sol | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/script/Deploy_All.s.sol b/script/Deploy_All.s.sol index ec269a5..352d3dc 100644 --- a/script/Deploy_All.s.sol +++ b/script/Deploy_All.s.sol @@ -26,7 +26,7 @@ contract DeployAll is Script { address constant COLLATERAL_ADDRESS = 0xeb762Ed11a09E4A394C9c8101f8aeeaf5382ED74; // eth sepolia uint256 constant MAX_WITHDRAW_AMOUNT = 1e9; // 10 iBTC uint256 constant MIN_WITHDRAW_AMOUNT = 1e4; - address constant GLOABAL_RECEIVER = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; //NOTE third address + address constant GLOBAL_RECEIVER = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; //NOTE third address // Replace with the correct checksummed addresses address constant VAULT_FACTORY = 0x407A039D94948484D356eFB765b3c74382A050B4; // Replace with deployed VaultFactory address @@ -52,7 +52,7 @@ contract DeployAll is Script { owner: owner, collateral: collateral, delay: 0, //NOTE we can set a delay - globalReceiver: GLOABAL_RECEIVER, + globalReceiver: GLOBAL_RECEIVER, networkReceivers: networkReceiver, operatorNetworkReceivers: operatorNetworkReceiver }); diff --git a/test/iBTC_NetworkMiddleware.t.sol b/test/iBTC_NetworkMiddleware.t.sol index 94a19c3..fd463bb 100644 --- a/test/iBTC_NetworkMiddleware.t.sol +++ b/test/iBTC_NetworkMiddleware.t.sol @@ -60,7 +60,7 @@ contract iBTC_NetworkMiddlewareTest is Test { address constant NETWORK = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; // first address network should be a multisig contract address constant OWNER = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8; // second address - address constant GLOABAL_RECEIVER = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; //NOTE third address + address constant GLOBAL_RECEIVER = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC; //NOTE third address uint48 constant EPOCH_DURATION = 7 days; // uint48 constant NETWORK_EPOCH = 5 days; @@ -120,7 +120,7 @@ contract iBTC_NetworkMiddlewareTest is Test { owner: OWNER, collateral: COLLATTERAL, delay: 0, //NOTE we can set a delay - globalReceiver: GLOABAL_RECEIVER, + globalReceiver: GLOBAL_RECEIVER, networkReceivers: networkReceiver, operatorNetworkReceivers: operatorNetworkReceiver }); @@ -352,7 +352,7 @@ contract iBTC_NetworkMiddlewareTest is Test { assertEq( iBTC_networkMiddleware.getOperatorStake(alice, epoch), iBTC_delegator.stake(NETWORK.subnetwork(0), alice), - "stake should same" + "stake should be the same" ); uint256 cachedStake = iBTC_networkMiddleware.calcAndCacheStakes(epoch);