From 1d0e9abfbd7b7cdc9223d775ef8097d2b8bf1aa8 Mon Sep 17 00:00:00 2001 From: nxqbao Date: Wed, 24 Jan 2024 18:23:47 +0700 Subject: [PATCH] temp: make BridgeManager is Proxy --- .../MainchainBridgeManagerDeploy.s.sol | 32 +- .../BridgeManager.sol | 33 +- .../BridgeManagerCallbackRegister.sol | 18 +- .../BridgeManagerQuorum.sol | 8 +- .../sequential-governance/CoreGovernance.sol | 7 +- .../GlobalCoreGovernance.sol | 7 +- src/mainchain/MainchainBridgeManager.sol | 36 +- src/mocks/ronin/MockBridgeManager.sol | 10 +- src/mocks/ronin/MockRoninBridgeManager.sol | 54 +-- src/ronin/gateway/RoninBridgeManager.sol | 21 +- test/bridge/integration/BaseIntegration.t.sol | 20 +- .../bridge-manager/BridgeManager.t.sol | 155 -------- .../concrete/bridge-manager/add/add.t.sol | 154 -------- .../unit/concrete/bridge-manager/add/add.tree | 16 - .../concrete/bridge-manager/constructor.t.sol | 62 ---- .../bridge-manager/remove/remove.t.sol | 138 -------- .../bridge-manager/remove/remove.tree | 24 -- .../bridge-manager/update/update.t.sol | 120 ------- .../bridge-manager/update/update.tree | 20 -- .../concrete/bridge-reward/BridgeReward.t.sol | 82 ----- .../execSyncReward/execSyncReward.t.sol | 335 ------------------ .../execSyncReward/execSyncReward.tree | 26 -- .../bridge-manager/BridgeManagerCRUD.t.sol | 221 ------------ .../fuzz/bridge-manager/BridgeReward.t.sol | 274 -------------- .../fuzz/bridge-manager/BridgeSlash.t.sol | 334 ----------------- 25 files changed, 161 insertions(+), 2046 deletions(-) delete mode 100644 test/bridge/unit/concrete/bridge-manager/BridgeManager.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-manager/add/add.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-manager/add/add.tree delete mode 100644 test/bridge/unit/concrete/bridge-manager/constructor.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-manager/remove/remove.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-manager/remove/remove.tree delete mode 100644 test/bridge/unit/concrete/bridge-manager/update/update.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-manager/update/update.tree delete mode 100644 test/bridge/unit/concrete/bridge-reward/BridgeReward.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.t.sol delete mode 100644 test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.tree delete mode 100644 test/bridge/unit/fuzz/bridge-manager/BridgeManagerCRUD.t.sol delete mode 100644 test/bridge/unit/fuzz/bridge-manager/BridgeReward.t.sol delete mode 100644 test/bridge/unit/fuzz/bridge-manager/BridgeSlash.t.sol diff --git a/script/contracts/MainchainBridgeManagerDeploy.s.sol b/script/contracts/MainchainBridgeManagerDeploy.s.sol index 31cc13f3..de06f374 100644 --- a/script/contracts/MainchainBridgeManagerDeploy.s.sol +++ b/script/contracts/MainchainBridgeManagerDeploy.s.sol @@ -9,24 +9,24 @@ import { Migration } from "../Migration.s.sol"; import { MainchainGatewayV3Deploy } from "./MainchainGatewayV3Deploy.s.sol"; contract MainchainBridgeManagerDeploy is Migration { - function _defaultArguments() internal virtual override returns (bytes memory args) { - ISharedArgument.BridgeManagerParam memory param = config.sharedArguments().mainchainBridgeManager; + // function _defaultArguments() internal virtual override returns (bytes memory args) { + // ISharedArgument.BridgeManagerParam memory param = config.sharedArguments().mainchainBridgeManager; - args = abi.encode( - param.num, - param.denom, - param.roninChainId, - param.bridgeContract, - param.callbackRegisters, - param.bridgeOperators, - param.governors, - param.voteWeights, - param.targetOptions, - param.targets - ); - } + // args = abi.encode( + // param.num, + // param.denom, + // param.roninChainId, + // param.bridgeContract, + // param.callbackRegisters, + // param.bridgeOperators, + // param.governors, + // param.voteWeights, + // param.targetOptions, + // param.targets + // ); + // } function run() public virtual returns (MainchainBridgeManager) { - return MainchainBridgeManager(_deployImmutable(Contract.MainchainBridgeManager.key())); + return MainchainBridgeManager(_deployProxy(Contract.MainchainBridgeManager.key(), EMPTY_ARGS)); } } diff --git a/src/extensions/bridge-operator-governance/BridgeManager.sol b/src/extensions/bridge-operator-governance/BridgeManager.sol index a15d0dfe..c6b8ad12 100644 --- a/src/extensions/bridge-operator-governance/BridgeManager.sol +++ b/src/extensions/bridge-operator-governance/BridgeManager.sol @@ -36,7 +36,7 @@ abstract contract BridgeManager is IBridgeManager, HasContracts, BridgeManagerQu /** * @inheritdoc IBridgeManager */ - bytes32 public immutable DOMAIN_SEPARATOR; + bytes32 public DOMAIN_SEPARATOR; function _getBridgeManagerStorage() private pure returns (BridgeManagerStorage storage $) { assembly { @@ -49,7 +49,31 @@ abstract contract BridgeManager is IBridgeManager, HasContracts, BridgeManagerQu _; } - constructor( + // constructor( + // uint256 num, + // uint256 denom, + // uint256 roninChainId, + // address bridgeContract, + // address[] memory callbackRegisters, + // address[] memory bridgeOperators, + // address[] memory governors, + // uint96[] memory voteWeights + // ) payable BridgeManagerQuorum(num, denom) BridgeManagerCallbackRegister(callbackRegisters) { + // // _setContract(ContractType.BRIDGE, bridgeContract); + + // // DOMAIN_SEPARATOR = keccak256( + // // abi.encode( + // // keccak256("EIP712Domain(string name,string version,bytes32 salt)"), + // // keccak256("BridgeAdmin"), // name hash + // // keccak256("2"), // version hash + // // keccak256(abi.encode("BRIDGE_ADMIN", roninChainId)) // salt + // // ) + // // ); + + // // _addBridgeOperators(voteWeights, governors, bridgeOperators); + // } + + function __init( uint256 num, uint256 denom, uint256 roninChainId, @@ -58,7 +82,10 @@ abstract contract BridgeManager is IBridgeManager, HasContracts, BridgeManagerQu address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights - ) payable BridgeManagerQuorum(num, denom) BridgeManagerCallbackRegister(callbackRegisters) { + ) internal { + BridgeManagerQuorum.__init(num, denom); + BridgeManagerCallbackRegister.__init(callbackRegisters); + _setContract(ContractType.BRIDGE, bridgeContract); DOMAIN_SEPARATOR = keccak256( diff --git a/src/extensions/bridge-operator-governance/BridgeManagerCallbackRegister.sol b/src/extensions/bridge-operator-governance/BridgeManagerCallbackRegister.sol index 32efcef6..f17f6daa 100644 --- a/src/extensions/bridge-operator-governance/BridgeManagerCallbackRegister.sol +++ b/src/extensions/bridge-operator-governance/BridgeManagerCallbackRegister.sol @@ -19,7 +19,11 @@ abstract contract BridgeManagerCallbackRegister is IdentityGuard, IBridgeManager */ bytes32 private constant CALLBACK_REGISTERS_SLOT = 0x5da136eb38f8d8e354915fc8a767c0dc81d49de5fb65d5477122a82ddd976240; - constructor(address[] memory callbackRegisters) payable { + // constructor(address[] memory callbackRegisters) payable { + // // _registerCallbacks(callbackRegisters); + // } + + function __init(address[] memory callbackRegisters) internal { _registerCallbacks(callbackRegisters); } @@ -33,9 +37,7 @@ abstract contract BridgeManagerCallbackRegister is IdentityGuard, IBridgeManager /** * @inheritdoc IBridgeManagerCallbackRegister */ - function unregisterCallbacks( - address[] calldata registers - ) external onlySelfCall returns (bool[] memory unregistereds) { + function unregisterCallbacks(address[] calldata registers) external onlySelfCall returns (bool[] memory unregistereds) { unregistereds = _unregisterCallbacks(registers); } @@ -51,9 +53,7 @@ abstract contract BridgeManagerCallbackRegister is IdentityGuard, IBridgeManager * @param registers The array of callback addresses to register. * @return registereds An array indicating the success status of each registration. */ - function _registerCallbacks( - address[] memory registers - ) internal nonDuplicate(registers) returns (bool[] memory registereds) { + function _registerCallbacks(address[] memory registers) internal nonDuplicate(registers) returns (bool[] memory registereds) { uint256 length = registers.length; registereds = new bool[](length); if (length == 0) return registereds; @@ -81,9 +81,7 @@ abstract contract BridgeManagerCallbackRegister is IdentityGuard, IBridgeManager * @param registers The array of callback addresses to unregister. * @return unregistereds An array indicating the success status of each unregistration. */ - function _unregisterCallbacks( - address[] memory registers - ) internal nonDuplicate(registers) returns (bool[] memory unregistereds) { + function _unregisterCallbacks(address[] memory registers) internal nonDuplicate(registers) returns (bool[] memory unregistereds) { uint256 length = registers.length; unregistereds = new bool[](length); EnumerableSet.AddressSet storage _callbackRegisters = _getCallbackRegisters(); diff --git a/src/extensions/bridge-operator-governance/BridgeManagerQuorum.sol b/src/extensions/bridge-operator-governance/BridgeManagerQuorum.sol index 705656d9..bc7864c9 100644 --- a/src/extensions/bridge-operator-governance/BridgeManagerQuorum.sol +++ b/src/extensions/bridge-operator-governance/BridgeManagerQuorum.sol @@ -21,7 +21,13 @@ abstract contract BridgeManagerQuorum is IQuorum, IdentityGuard { } } - constructor(uint256 num, uint256 denom) { + // constructor(uint256 num, uint256 denom) { + // // BridgeManagerQuorumStorage storage $ = _getBridgeManagerQuorumStorage(); + // // $._nonce = 1; + // // _setThreshold(num, denom); + // } + + function __init(uint256 num, uint256 denom) internal { BridgeManagerQuorumStorage storage $ = _getBridgeManagerQuorumStorage(); $._nonce = 1; diff --git a/src/extensions/sequential-governance/CoreGovernance.sol b/src/extensions/sequential-governance/CoreGovernance.sol index 93e03c2f..4c7529b1 100644 --- a/src/extensions/sequential-governance/CoreGovernance.sol +++ b/src/extensions/sequential-governance/CoreGovernance.sol @@ -63,10 +63,15 @@ abstract contract CoreGovernance is SignatureConsumer, VoteStatusConsumer, Chain uint256 internal _proposalExpiryDuration; - constructor(uint256 _expiryDuration) { + // constructor(uint256 _expiryDuration) { + // // _setProposalExpiryDuration(_expiryDuration); + // } + +function __init(uint256 _expiryDuration) internal { _setProposalExpiryDuration(_expiryDuration); } + /** * @dev Creates new voting round by calculating the `_round` number of chain `_chainId`. * Increases the `_round` number if the previous one is not expired. Delete the previous proposal diff --git a/src/extensions/sequential-governance/GlobalCoreGovernance.sol b/src/extensions/sequential-governance/GlobalCoreGovernance.sol index 73e1fbeb..b6a2acad 100644 --- a/src/extensions/sequential-governance/GlobalCoreGovernance.sol +++ b/src/extensions/sequential-governance/GlobalCoreGovernance.sol @@ -24,7 +24,12 @@ abstract contract GlobalCoreGovernance is CoreGovernance { /// @dev Emitted when the target options are updated event TargetOptionUpdated(GlobalProposal.TargetOption indexed targetOption, address indexed addr); - constructor(GlobalProposal.TargetOption[] memory targetOptions, address[] memory addrs) { + // constructor(GlobalProposal.TargetOption[] memory targetOptions, address[] memory addrs) { + // // _updateTargetOption(GlobalProposal.TargetOption.BridgeManager, address(this)); + // // _updateManyTargetOption(targetOptions, addrs); + // } + + function __init(GlobalProposal.TargetOption[] memory targetOptions, address[] memory addrs) internal { _updateTargetOption(GlobalProposal.TargetOption.BridgeManager, address(this)); _updateManyTargetOption(targetOptions, addrs); } diff --git a/src/mainchain/MainchainBridgeManager.sol b/src/mainchain/MainchainBridgeManager.sol index ff9934d5..207bd49e 100644 --- a/src/mainchain/MainchainBridgeManager.sol +++ b/src/mainchain/MainchainBridgeManager.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import { CoreGovernance } from "../extensions/sequential-governance/CoreGovernance.sol"; import { GlobalCoreGovernance, GlobalGovernanceRelay } from "../extensions/sequential-governance/governance-relay/GlobalGovernanceRelay.sol"; import { GovernanceRelay } from "../extensions/sequential-governance/governance-relay/GovernanceRelay.sol"; @@ -10,10 +11,30 @@ import { Proposal } from "../libraries/Proposal.sol"; import { GlobalProposal } from "../libraries/GlobalProposal.sol"; import "../utils/CommonErrors.sol"; -contract MainchainBridgeManager is BridgeManager, GovernanceRelay, GlobalGovernanceRelay { +contract MainchainBridgeManager is Initializable, BridgeManager, GovernanceRelay, GlobalGovernanceRelay { uint256 private constant DEFAULT_EXPIRY_DURATION = 1 << 255; - constructor( + constructor() + // uint256 num, + // uint256 denom, + // uint256 roninChainId, + // address bridgeContract, + // address[] memory callbackRegisters, + // address[] memory bridgeOperators, + // address[] memory governors, + // uint96[] memory voteWeights, + // GlobalProposal.TargetOption[] memory targetOptions, + // address[] memory targets + // ) + // payable + // CoreGovernance(DEFAULT_EXPIRY_DURATION) + // GlobalCoreGovernance(targetOptions, targets) + // BridgeManager(num, denom, roninChainId, bridgeContract, callbackRegisters, bridgeOperators, governors, voteWeights) + { + _disableInitializers(); + } + + function initialize( uint256 num, uint256 denom, uint256 roninChainId, @@ -24,12 +45,11 @@ contract MainchainBridgeManager is BridgeManager, GovernanceRelay, GlobalGoverna uint96[] memory voteWeights, GlobalProposal.TargetOption[] memory targetOptions, address[] memory targets - ) - payable - CoreGovernance(DEFAULT_EXPIRY_DURATION) - GlobalCoreGovernance(targetOptions, targets) - BridgeManager(num, denom, roninChainId, bridgeContract, callbackRegisters, bridgeOperators, governors, voteWeights) - {} + ) external initializer { + CoreGovernance.__init(DEFAULT_EXPIRY_DURATION); + GlobalCoreGovernance.__init(targetOptions, targets); + BridgeManager.__init(num, denom, roninChainId, bridgeContract, callbackRegisters, bridgeOperators, governors, voteWeights); + } /** * @dev See `GovernanceRelay-_relayProposal`. diff --git a/src/mocks/ronin/MockBridgeManager.sol b/src/mocks/ronin/MockBridgeManager.sol index a7dbe01a..84345bb7 100644 --- a/src/mocks/ronin/MockBridgeManager.sol +++ b/src/mocks/ronin/MockBridgeManager.sol @@ -4,11 +4,11 @@ pragma solidity ^0.8.0; import { RoleAccess, ContractType, AddressArrayUtils, IBridgeManager, BridgeManager } from "../../extensions/bridge-operator-governance/BridgeManager.sol"; contract MockBridgeManager is BridgeManager { - constructor( - address[] memory bridgeOperators, - address[] memory governors, - uint96[] memory voteWeights - ) payable BridgeManager(0, 0, 0, address(0), _getEmptyAddressArray(), bridgeOperators, governors, voteWeights) {} + // constructor( + // address[] memory bridgeOperators, + // address[] memory governors, + // uint96[] memory voteWeights + // ) payable BridgeManager(0, 0, 0, address(0), _getEmptyAddressArray(), bridgeOperators, governors, voteWeights) {} function _getEmptyAddressArray() internal pure returns (address[] memory arr) {} } diff --git a/src/mocks/ronin/MockRoninBridgeManager.sol b/src/mocks/ronin/MockRoninBridgeManager.sol index 4d7daa76..867caa19 100644 --- a/src/mocks/ronin/MockRoninBridgeManager.sol +++ b/src/mocks/ronin/MockRoninBridgeManager.sol @@ -5,31 +5,31 @@ import { RoninBridgeManager } from "../../ronin/gateway/RoninBridgeManager.sol"; import { GlobalProposal } from "../../extensions/sequential-governance/governance-proposal/GovernanceProposal.sol"; contract MockRoninBridgeManager is RoninBridgeManager { - constructor( - uint256 num, - uint256 denom, - uint256 roninChainId, - uint256 expiryDuration, - address bridgeContract, - address[] memory callbackRegisters, - address[] memory bridgeOperators, - address[] memory governors, - uint96[] memory voteWeights, - GlobalProposal.TargetOption[] memory targetOptions, - address[] memory targets - ) - RoninBridgeManager( - num, - denom, - roninChainId, - expiryDuration, - bridgeContract, - callbackRegisters, - bridgeOperators, - governors, - voteWeights, - targetOptions, - targets - ) - {} + // constructor( + // uint256 num, + // uint256 denom, + // uint256 roninChainId, + // uint256 expiryDuration, + // address bridgeContract, + // address[] memory callbackRegisters, + // address[] memory bridgeOperators, + // address[] memory governors, + // uint96[] memory voteWeights, + // GlobalProposal.TargetOption[] memory targetOptions, + // address[] memory targets + // ) + // RoninBridgeManager( + // num, + // denom, + // roninChainId, + // expiryDuration, + // bridgeContract, + // callbackRegisters, + // bridgeOperators, + // governors, + // voteWeights, + // targetOptions, + // targets + // ) + // {} } diff --git a/src/ronin/gateway/RoninBridgeManager.sol b/src/ronin/gateway/RoninBridgeManager.sol index 7c4084c7..1ad54f7d 100644 --- a/src/ronin/gateway/RoninBridgeManager.sol +++ b/src/ronin/gateway/RoninBridgeManager.sol @@ -8,7 +8,8 @@ import { VoteStatusConsumer } from "../../interfaces/consumers/VoteStatusConsume import { ErrQueryForEmptyVote } from "../../utils/CommonErrors.sol"; contract RoninBridgeManager is BridgeManager, GovernanceProposal, GlobalGovernanceProposal { - constructor( + + function initialize( uint256 num, uint256 denom, uint256 roninChainId, @@ -19,13 +20,12 @@ contract RoninBridgeManager is BridgeManager, GovernanceProposal, GlobalGovernan address[] memory governors, uint96[] memory voteWeights, GlobalProposal.TargetOption[] memory targetOptions, - address[] memory targets - ) - payable - CoreGovernance(expiryDuration) - GlobalCoreGovernance(targetOptions, targets) - BridgeManager(num, denom, roninChainId, bridgeContract, callbackRegisters, bridgeOperators, governors, voteWeights) - {} + address[] memory targets) external + { + CoreGovernance.__init(expiryDuration); + GlobalCoreGovernance.__init(targetOptions, targets); + BridgeManager.__init(num, denom, roninChainId, bridgeContract, callbackRegisters, bridgeOperators, governors, voteWeights); + } /** * CURRENT NETWORK @@ -101,10 +101,7 @@ contract RoninBridgeManager is BridgeManager, GovernanceProposal, GlobalGovernan * - The method caller is governor. * */ - function castProposalVoteForCurrentNetwork( - Proposal.ProposalDetail calldata proposal, - Ballot.VoteType support - ) external onlyGovernor { + function castProposalVoteForCurrentNetwork(Proposal.ProposalDetail calldata proposal, Ballot.VoteType support) external onlyGovernor { _castProposalVoteForCurrentNetwork(msg.sender, proposal, support); } diff --git a/test/bridge/integration/BaseIntegration.t.sol b/test/bridge/integration/BaseIntegration.t.sol index 6c820340..2cce9ee6 100644 --- a/test/bridge/integration/BaseIntegration.t.sol +++ b/test/bridge/integration/BaseIntegration.t.sol @@ -84,7 +84,7 @@ contract BaseIntegration_Test is Base_Test { _deployContractsOnRonin(); _deployContractsOnMainchain(); - _initializeRonin(); + // _initializeRonin(); _initializeMainchain(); } @@ -140,6 +140,7 @@ contract BaseIntegration_Test is Base_Test { function _initializeMainchain() internal { _config.switchTo(Network.EthLocal.key()); + _mainchainBridgeManagerInitialize(); _constructForMainchainBridgeManager(); _mainchainGatewayV3Initialize(); } @@ -380,6 +381,23 @@ contract BaseIntegration_Test is Base_Test { } } + function _mainchainBridgeManagerInitialize() internal { + ISharedArgument.BridgeManagerParam memory param = _param.mainchainBridgeManager; + + _mainchainBridgeManager.initialize( + param.num, + param.denom, + param.roninChainId, + param.bridgeContract, + param.callbackRegisters, + param.bridgeOperators, + param.governors, + param.voteWeights, + param.targetOptions, + param.targets + ); + } + function _mainchainGatewayV3Initialize() internal { (address[] memory mainchainTokens, address[] memory roninTokens) = _getMainchainAndRoninTokens(); uint256 tokenNum = mainchainTokens.length; diff --git a/test/bridge/unit/concrete/bridge-manager/BridgeManager.t.sol b/test/bridge/unit/concrete/bridge-manager/BridgeManager.t.sol deleted file mode 100644 index 78ed19fe..00000000 --- a/test/bridge/unit/concrete/bridge-manager/BridgeManager.t.sol +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { Base_Test } from "@ronin/test/Base.t.sol"; - -import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; -import { MockBridgeManager } from "@ronin/contracts/mocks/ronin/MockBridgeManager.sol"; - -contract BridgeManager_Unit_Concrete_Test is Base_Test { - IBridgeManager internal _bridgeManager; - address[] internal _bridgeOperators; - address[] internal _governors; - uint96[] internal _voteWeights; - uint256 internal _totalWeight; - uint256 internal _totalOperator; - - modifier assertStateNotChange() { - // Get before test state - (address[] memory beforeBridgeOperators, address[] memory beforeGovernors, uint96[] memory beforeVoteWeights) = _getBridgeMembers(); - - _; - - // Compare after and before state - (address[] memory afterBridgeOperators, address[] memory afterGovernors, uint96[] memory afterVoteWeights) = _getBridgeMembers(); - - _assertBridgeMembers({ - comparingOperators: beforeBridgeOperators, - expectingOperators: afterBridgeOperators, - comparingGovernors: beforeGovernors, - expectingGovernors: afterGovernors, - comparingWeights: beforeVoteWeights, - expectingWeights: afterVoteWeights - }); - assertEq(_bridgeManager.getTotalWeight(), _totalWeight); - } - - function setUp() public virtual { - address[] memory bridgeOperators = new address[](3); - bridgeOperators[0] = address(0x10000); - bridgeOperators[1] = address(0x10001); - bridgeOperators[2] = address(0x10002); - - address[] memory governors = new address[](3); - governors[0] = address(0x20000); - governors[1] = address(0x20001); - governors[2] = address(0x20002); - - uint96[] memory voteWeights = new uint96[](3); - voteWeights[0] = 100; - voteWeights[1] = 100; - voteWeights[2] = 100; - - for (uint i; i < bridgeOperators.length; i++) { - _bridgeOperators.push(bridgeOperators[i]); - _governors.push(governors[i]); - _voteWeights.push(voteWeights[i]); - } - - _totalWeight = 300; - _totalOperator = 3; - - _bridgeManager = new MockBridgeManager(bridgeOperators, governors, voteWeights); - } - - function _generateNewOperators() internal pure returns (address[] memory operators, address[] memory governors, uint96[] memory weights) { - operators = new address[](1); - operators[0] = address(0x10003); - - governors = new address[](1); - governors[0] = address(0x20003); - - weights = new uint96[](1); - weights[0] = 100; - } - - function _generateRemovingOperators( - uint removingNumber - ) - internal - view - returns ( - address[] memory removingOperators, - address[] memory removingGovernors, - uint96[] memory removingWeights, - address[] memory remainingOperators, - address[] memory remainingGovernors, - uint96[] memory remainingWeights - ) - { - if (removingNumber > _totalOperator) { - revert("_generateRemovingOperators: exceed number to remove"); - } - - uint remainingNumber = _totalOperator - removingNumber; - - removingOperators = new address[](removingNumber); - removingGovernors = new address[](removingNumber); - removingWeights = new uint96[](removingNumber); - remainingOperators = new address[](remainingNumber); - remainingGovernors = new address[](remainingNumber); - remainingWeights = new uint96[](remainingNumber); - - for (uint i; i < removingNumber; i++) { - removingOperators[i] = _bridgeOperators[i]; - removingGovernors[i] = _governors[i]; - removingWeights[i] = _voteWeights[i]; - } - - for (uint i = removingNumber; i < _totalOperator; i++) { - remainingOperators[i - removingNumber] = _bridgeOperators[i]; - remainingGovernors[i - removingNumber] = _governors[i]; - remainingWeights[i - removingNumber] = _voteWeights[i]; - } - } - - function _generateBridgeOperatorAddressToUpdate() internal pure returns (address) { - return address(0x10010); - } - - function _getBridgeMembers() internal view returns (address[] memory operators, address[] memory governors, uint96[] memory weights) { - // (governors, operators, weights) = _bridgeManager.getFullBridgeOperatorInfos(); - address[] memory governors_ = _bridgeManager.getGovernors(); - return _getBridgeMembersByGovernors(governors_); - } - - function _getBridgeMembersByGovernors( - address[] memory queryingGovernors - ) internal view returns (address[] memory operators, address[] memory governors, uint96[] memory weights) { - governors = queryingGovernors; - - operators = new address[](queryingGovernors.length); - for (uint i; i < queryingGovernors.length; i++) { - operators[i] = _bridgeManager.getOperatorOf(queryingGovernors[i]); - } - - weights = _bridgeManager.getGovernorWeights(queryingGovernors); - } - - function _assertBridgeMembers( - address[] memory comparingOperators, - address[] memory expectingOperators, - address[] memory comparingGovernors, - address[] memory expectingGovernors, - uint96[] memory comparingWeights, - uint96[] memory expectingWeights - ) internal { - assertEq(comparingOperators.length, expectingOperators.length, "wrong bridge operators length"); - assertEq(comparingGovernors.length, expectingGovernors.length, "wrong governors length"); - assertEq(comparingWeights.length, expectingWeights.length, "wrong weights length"); - - assertEq(comparingOperators, expectingOperators, "wrong bridge operators"); - assertEq(comparingGovernors, expectingGovernors, "wrong governors"); - assertEq(comparingWeights, expectingWeights, "wrong weights"); - } -} diff --git a/test/bridge/unit/concrete/bridge-manager/add/add.t.sol b/test/bridge/unit/concrete/bridge-manager/add/add.t.sol deleted file mode 100644 index fe92ff02..00000000 --- a/test/bridge/unit/concrete/bridge-manager/add/add.t.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { console2 } from "forge-std/console2.sol"; -import { StdStyle } from "forge-std/StdStyle.sol"; - -import { LibArrayUtils } from "@ronin/test/helpers/LibArrayUtils.t.sol"; - -import "@ronin/contracts/utils/CommonErrors.sol"; -import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; - -import { BridgeManager_Unit_Concrete_Test } from "../BridgeManager.t.sol"; - -contract Add_Unit_Concrete_Test is BridgeManager_Unit_Concrete_Test { - function setUp() public virtual override { - BridgeManager_Unit_Concrete_Test.setUp(); - vm.startPrank({ msgSender: address(_bridgeManager) }); - } - - function test_RevertWhen_NotSelfCall() external { - // Prepare data - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - // Make the caller not self-call. - changePrank({ msgSender: _bridgeOperators[0] }); - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(ErrOnlySelfCall.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - } - - function test_RevertWhen_ThreeInputArrayLengthMismatch() external { - // Prepare data - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - uint length = addingOperators.length; - - assembly { - mstore(addingOperators, add(length, 1)) - } - vm.expectRevert(abi.encodeWithSelector(ErrLengthMismatch.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - - assembly { - mstore(addingOperators, length) - mstore(addingGovernors, add(length, 1)) - } - vm.expectRevert(abi.encodeWithSelector(ErrLengthMismatch.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - - assembly { - mstore(addingGovernors, length) - mstore(addingWeights, add(length, 1)) - } - vm.expectRevert(abi.encodeWithSelector(ErrLengthMismatch.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - } - - function test_RevertWhen_VoteWeightIsZero() external { - // Prepare data - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingWeights[0] = 0; - vm.expectRevert(abi.encodeWithSelector(ErrInvalidVoteWeight.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - } - - function test_RevertWhen_BridgeOperatorAddressIsZero() external { - // Prepare data - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingOperators[0] = address(0); - vm.expectRevert(abi.encodeWithSelector(ErrZeroAddress.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - } - - function test_RevertWhen_GovernorAddressIsZero() external { - // Prepare data - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingGovernors[0] = address(0); - vm.expectRevert(abi.encodeWithSelector(ErrZeroAddress.selector, IBridgeManager.addBridgeOperators.selector)); - _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - } - - function test_AddOperators_DuplicatedGovernor() external assertStateNotChange { - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingGovernors[0] = _governors[0]; - bool[] memory addeds = _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - bool[] memory expectedAddeds = new bool[](1); - expectedAddeds[0] = false; - assertEq(addeds, expectedAddeds); - } - - function test_AddOperators_DuplicatedBridgeOperator() external assertStateNotChange { - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingOperators[0] = _bridgeOperators[0]; - bool[] memory addeds = _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - bool[] memory expectedAddeds = new bool[](1); - expectedAddeds[0] = false; - assertEq(addeds, expectedAddeds); - } - - function test_AddOperators_DuplicatedGovernorWithExistedBridgeOperator() external assertStateNotChange { - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingGovernors[0] = _bridgeOperators[0]; - bool[] memory addeds = _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - bool[] memory expectedAddeds = new bool[](1); - expectedAddeds[0] = false; - assertEq(addeds, expectedAddeds); - } - - function test_AddOperators_DuplicatedBridgeOperatorWithExistedGovernor() external assertStateNotChange { - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - addingOperators[0] = _governors[0]; - bool[] memory addeds = _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - bool[] memory expectedAddeds = new bool[](1); - expectedAddeds[0] = false; - assertEq(addeds, expectedAddeds); - } - - function test_AddOperators_AllInfoIsValid() external { - // Get before test state - (address[] memory beforeBridgeOperators, address[] memory beforeGovernors, uint96[] memory beforeVoteWeights) = _getBridgeMembers(); - (address[] memory addingOperators, address[] memory addingGovernors, uint96[] memory addingWeights) = _generateNewOperators(); - - bool[] memory addeds = _bridgeManager.addBridgeOperators(addingWeights, addingGovernors, addingOperators); - bool[] memory expectedAddeds = new bool[](1); - expectedAddeds[0] = true; - assertEq(addeds, expectedAddeds); - - // Compare after and before state - (address[] memory afterBridgeOperators, address[] memory afterGovernors, uint96[] memory afterVoteWeights) = _getBridgeMembers(); - _totalWeight += addingWeights[0]; - - address[] memory expectingOperators = LibArrayUtils.concat(beforeBridgeOperators, addingOperators); - address[] memory expectingGovernors = LibArrayUtils.concat(beforeGovernors, addingGovernors); - uint96[] memory expectingWeights = LibArrayUtils.concat(beforeVoteWeights, addingWeights); - - _assertBridgeMembers({ - comparingOperators: afterBridgeOperators, - comparingGovernors: afterGovernors, - comparingWeights: afterVoteWeights, - expectingOperators: expectingOperators, - expectingGovernors: expectingGovernors, - expectingWeights: expectingWeights - }); - assertEq(_bridgeManager.getTotalWeight(), _totalWeight); - } -} diff --git a/test/bridge/unit/concrete/bridge-manager/add/add.tree b/test/bridge/unit/concrete/bridge-manager/add/add.tree deleted file mode 100644 index a0b33b54..00000000 --- a/test/bridge/unit/concrete/bridge-manager/add/add.tree +++ /dev/null @@ -1,16 +0,0 @@ -add.t.sol - when not self-called - it should revert - when self-called - when the three input arrays length mismatch - it should revert - when the vote weight or the address is zero - it should revert - when duplicated governor - it should revert - when duplicated bridge operator - it should revert - when the info is valid - it should add gorvernor to the governor list - it should add bridge operator to the operator list - it should grant the governor the expected weight diff --git a/test/bridge/unit/concrete/bridge-manager/constructor.t.sol b/test/bridge/unit/concrete/bridge-manager/constructor.t.sol deleted file mode 100644 index 06e48220..00000000 --- a/test/bridge/unit/concrete/bridge-manager/constructor.t.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { console } from "forge-std/console.sol"; -import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; -import { IBridgeManagerEvents } from "@ronin/contracts/interfaces/bridge/events/IBridgeManagerEvents.sol"; - -import { BridgeManager_Unit_Concrete_Test } from "./BridgeManager.t.sol"; - -contract Constructor_BridgeManager_Unit_Concrete_Test is BridgeManager_Unit_Concrete_Test { - function test_Constructor() external { - // Expect the relevant event to be emitted. - // bool[] memory statuses = new bool[](3); - // statuses[0] = true; - // statuses[1] = true; - // statuses[2] = true; - - // vm.expectEmit(); - // emit IBridgeManagerEvents.BridgeOperatorsAdded({ - // statuses: statuses, - // voteWeights: _voteWeights, - // governors: _governors, - // bridgeOperators: _bridgeOperators - // }); - - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = _getBridgeMembers(); - - _assertBridgeMembers({ - comparingOperators: _bridgeOperators, - expectingOperators: bridgeOperators, - comparingGovernors: _governors, - expectingGovernors: governors, - comparingWeights: _voteWeights, - expectingWeights: voteWeights - }); - assertEq(_bridgeManager.totalBridgeOperator(), 3); - assertEq(_bridgeManager.getTotalWeight(), _totalWeight); - } - - function test_GetFullBridgeOperatorInfos() external { - ( - address[] memory expectingBridgeOperators, - address[] memory expectingGovernors, - uint96[] memory expectingVoteWeights - ) = _getBridgeMembers(); - - ( - address[] memory returnedGovernors, - address[] memory returnedBridgeOperators, - uint96[] memory returnedVoteWeights - ) = _bridgeManager.getFullBridgeOperatorInfos(); - - _assertBridgeMembers({ - comparingOperators: returnedBridgeOperators, - comparingGovernors: returnedGovernors, - comparingWeights: returnedVoteWeights, - expectingOperators: expectingBridgeOperators, - expectingGovernors: expectingGovernors, - expectingWeights: expectingVoteWeights - }); - } -} diff --git a/test/bridge/unit/concrete/bridge-manager/remove/remove.t.sol b/test/bridge/unit/concrete/bridge-manager/remove/remove.t.sol deleted file mode 100644 index 96318586..00000000 --- a/test/bridge/unit/concrete/bridge-manager/remove/remove.t.sol +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { console2 } from "forge-std/console2.sol"; -import { StdStyle } from "forge-std/StdStyle.sol"; - -import { LibArrayUtils } from "@ronin/test/helpers/LibArrayUtils.t.sol"; - -import "@ronin/contracts/utils/CommonErrors.sol"; -import { AddressArrayUtils } from "@ronin/contracts/libraries/AddressArrayUtils.sol"; -import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; - -import { BridgeManager_Unit_Concrete_Test } from "../BridgeManager.t.sol"; - -contract Remove_Unit_Concrete_Test is BridgeManager_Unit_Concrete_Test { - function setUp() public virtual override { - BridgeManager_Unit_Concrete_Test.setUp(); - vm.startPrank({ msgSender: address(_bridgeManager) }); - } - - function test_RevertWhen_NotSelfCall() external { - // Prepare data - (address[] memory removingOperators, , , , , ) = _generateRemovingOperators(1); - - // Make the caller not self-call. - changePrank({ msgSender: _bridgeOperators[0] }); - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(ErrOnlySelfCall.selector, IBridgeManager.removeBridgeOperators.selector)); - _bridgeManager.removeBridgeOperators(removingOperators); - } - - function test_RevertWhen_RemoveOperator_OneAddress_AddressNotOperator() external { - address[] memory removingOperators = wrapAddress(_governors[0]); - - vm.expectRevert(abi.encodeWithSelector(IBridgeManager.ErrOperatorNotFound.selector, removingOperators[0])); - _bridgeManager.removeBridgeOperators(removingOperators); - } - - function test_RemoveOperators_OneAddress_ThatValid() external { - ( - address[] memory removingOperators, - address[] memory removingGovernors, - uint96[] memory removingWeights, - address[] memory remainingOperators, - address[] memory remainingGovernors, - uint96[] memory remainingWeights - ) = _generateRemovingOperators(1); - - bool[] memory removeds = _bridgeManager.removeBridgeOperators(removingOperators); - bool[] memory expectedRemoved = new bool[](1); - expectedRemoved[0] = true; - assertEq(removeds, expectedRemoved); - - assertEq(_bridgeManager.totalBridgeOperator(), _bridgeOperators.length - 1, "wrong total bridge operator"); - assertEq(_bridgeManager.getTotalWeight(), _totalWeight - removingWeights[0], "wrong total total weight"); - - vm.expectRevert(abi.encodeWithSelector(IBridgeManager.ErrGovernorNotFound.selector, removingGovernors[0])); - _bridgeManager.getOperatorOf(removingGovernors[0]); - - vm.expectRevert(abi.encodeWithSelector(IBridgeManager.ErrOperatorNotFound.selector, removingOperators[0])); - _bridgeManager.getGovernorOf(removingOperators[0]); - - // Compare after and before state - (address[] memory afterBridgeOperators, address[] memory afterGovernors, uint96[] memory afterVoteWeights) = _getBridgeMembersByGovernors( - remainingGovernors - ); - - _assertBridgeMembers({ - comparingOperators: afterBridgeOperators, - comparingGovernors: afterGovernors, - comparingWeights: afterVoteWeights, - expectingOperators: remainingOperators, - expectingGovernors: remainingGovernors, - expectingWeights: remainingWeights - }); - } - - function test_RevertWhen_TwoAddress_Duplicated() external { - (address[] memory removingOperators, address[] memory removingGovernors, uint96[] memory removingWeights, , , ) = _generateRemovingOperators(2); - - removingOperators[1] = removingOperators[0]; - removingGovernors[1] = removingGovernors[0]; - removingWeights[1] = removingWeights[0]; - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(AddressArrayUtils.ErrDuplicated.selector, IBridgeManager.removeBridgeOperators.selector)); - _bridgeManager.removeBridgeOperators(removingOperators); - } - - function test_RemoveOperators_TwoAddress_ThatValid() external { - uint TO_REMOVE_NUM = 2; - - ( - address[] memory removingOperators, - address[] memory removingGovernors, - uint96[] memory removingWeights, - address[] memory remainingOperators, - address[] memory remainingGovernors, - uint96[] memory remainingWeights - ) = _generateRemovingOperators(TO_REMOVE_NUM); - - bool[] memory removeds = _bridgeManager.removeBridgeOperators(removingOperators); - bool[] memory expectedRemoved = new bool[](TO_REMOVE_NUM); - expectedRemoved[0] = true; - expectedRemoved[1] = true; - assertEq(removeds, expectedRemoved); - - address[] memory zeroAddressArrays = new address[](TO_REMOVE_NUM); - zeroAddressArrays[0] = address(0); - zeroAddressArrays[1] = address(0); - - assertEq(_bridgeManager.totalBridgeOperator(), _bridgeOperators.length - TO_REMOVE_NUM, "wrong total bridge operator"); - assertEq(_bridgeManager.getTotalWeight(), _totalWeight - (LibArrayUtils.sum(removingWeights)), "wrong total total weight"); - - for (uint i; i < TO_REMOVE_NUM; i++) { - vm.expectRevert(abi.encodeWithSelector(IBridgeManager.ErrGovernorNotFound.selector, removingGovernors[i])); - _bridgeManager.getOperatorOf(removingGovernors[i]); - - vm.expectRevert(abi.encodeWithSelector(IBridgeManager.ErrOperatorNotFound.selector, removingOperators[i])); - _bridgeManager.getGovernorOf(removingOperators[i]); - } - - // Compare after and before state - (address[] memory afterBridgeOperators, address[] memory afterGovernors, uint96[] memory afterVoteWeights) = _getBridgeMembersByGovernors( - remainingGovernors - ); - - _assertBridgeMembers({ - comparingOperators: afterBridgeOperators, - comparingGovernors: afterGovernors, - comparingWeights: afterVoteWeights, - expectingOperators: remainingOperators, - expectingGovernors: remainingGovernors, - expectingWeights: remainingWeights - }); - } -} diff --git a/test/bridge/unit/concrete/bridge-manager/remove/remove.tree b/test/bridge/unit/concrete/bridge-manager/remove/remove.tree deleted file mode 100644 index 04abb1e8..00000000 --- a/test/bridge/unit/concrete/bridge-manager/remove/remove.tree +++ /dev/null @@ -1,24 +0,0 @@ -remove.t.sol -├── when not self-called -│ └── it should revert -└── when self-called - ├── when the address contains one address - │ ├── when the address is not operator - │ │ └── it should revert - │ └── when the address is operator - │ ├── it should remove the gorvernor to the governor list - │ ├── it should remove the bridge operator to the operator list - │ ├── it should remove the governor the expected weight - │ ├── it should reduce total weight - │ ├── it should reduce total operator - │ ├── it should notify registers - │ ├── it should then return address zero when query by the removed governor - │ └── it should then return address zero when query by the removed operator - └── when the address contains two address - ├── when the address duplicated - └── when the address is not duplicated - ├── it should remove the gorvernor to the governor list - ├── it should remove the bridge operator to the operator list - ├── it should remove the governor the expected weight - ├── it should reduce total weight - └── it should notify registers \ No newline at end of file diff --git a/test/bridge/unit/concrete/bridge-manager/update/update.t.sol b/test/bridge/unit/concrete/bridge-manager/update/update.t.sol deleted file mode 100644 index 4b425d79..00000000 --- a/test/bridge/unit/concrete/bridge-manager/update/update.t.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { console2 } from "forge-std/console2.sol"; -import { StdStyle } from "forge-std/StdStyle.sol"; - -import "@ronin/contracts/utils/CommonErrors.sol"; -import { RoleAccess } from "@ronin/contracts/utils/RoleAccess.sol"; -import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; -import { IBridgeManagerEvents } from "@ronin/contracts/interfaces/bridge/events/IBridgeManagerEvents.sol"; - -import { BridgeManager_Unit_Concrete_Test } from "../BridgeManager.t.sol"; - -contract Update_Unit_Concrete_Test is BridgeManager_Unit_Concrete_Test { - address private _caller; // the governor to call the update - - function setUp() public virtual override { - BridgeManager_Unit_Concrete_Test.setUp(); - - _caller = _governors[0]; - vm.startPrank({ msgSender: _caller }); - } - - function test_RevertWhen_NotGovernorOfTheChangingBridgeOperator() external { - address newOperator = _generateBridgeOperatorAddressToUpdate(); - - // Make the caller not the governor. - changePrank({ msgSender: _bridgeOperators[0] }); - - // Run the test. - vm.expectRevert( - abi.encodeWithSelector( - ErrUnauthorized.selector, - IBridgeManager.updateBridgeOperator.selector, - RoleAccess.GOVERNOR - ) - ); - _bridgeManager.updateBridgeOperator(_bridgeOperators[0], newOperator); - } - - function test_RevertWhen_NewOperatorAddressIsZero() external { - address newOperator = address(0); - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(ErrZeroAddress.selector, IBridgeManager.updateBridgeOperator.selector)); - _bridgeManager.updateBridgeOperator(_bridgeOperators[0], newOperator); - } - - function test_RevertWhen_NewOperatorIsExistedInCurrentOperatorList() external { - address newOperator = _bridgeOperators[2]; - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(ErrBridgeOperatorAlreadyExisted.selector, newOperator)); - _bridgeManager.updateBridgeOperator(_bridgeOperators[0], newOperator); - } - - function test_RevertWhen_NewOperatorIsExistedInCurrentGovernorList() external { - vm.skip(true); - address newOperator = _governors[2]; - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(ErrZeroAddress.selector, IBridgeManager.updateBridgeOperator.selector)); // TODO: fix error sig here - _bridgeManager.updateBridgeOperator(_bridgeOperators[0], newOperator); - } - - function test_RevertWhen_NewOperatorIsTheSameWithPreviousOperator() external { - address prevOperator = _bridgeManager.getOperatorOf(_caller); - address newOperator = prevOperator; - - // Run the test. - vm.expectRevert(abi.encodeWithSelector(ErrBridgeOperatorAlreadyExisted.selector, prevOperator)); - _bridgeManager.updateBridgeOperator(_bridgeOperators[0], newOperator); - } - - function test_UpdateOperators_NewOperatorIsValid() external { - // Get before test state. - ( - address[] memory beforeBridgeOperators, - address[] memory beforeGovernors, - uint96[] memory beforeVoteWeights - ) = _getBridgeMembers(); - - // Prepare data. - address prevOperator = _bridgeManager.getOperatorOf(_caller); - address newOperator = _generateBridgeOperatorAddressToUpdate(); - - // Run the test - - // Should emit the event - vm.expectEmit({ emitter: address(_bridgeManager) }); - emit BridgeOperatorUpdated(_caller, prevOperator, newOperator); - - _bridgeManager.updateBridgeOperator(_bridgeOperators[0], newOperator); - - // Get after test state - ( - address[] memory afterBridgeOperators, - address[] memory afterGovernors, - uint96[] memory afterVoteWeights - ) = _getBridgeMembers(); - - // it should modify the current operators list - beforeBridgeOperators[0] = newOperator; - _assertBridgeMembers({ - comparingOperators: beforeBridgeOperators, - comparingGovernors: beforeGovernors, - comparingWeights: beforeVoteWeights, - expectingOperators: afterBridgeOperators, - expectingGovernors: afterGovernors, - expectingWeights: afterVoteWeights - }); - - // it should remove the old operator - assertEq(_bridgeManager.getOperatorOf(_caller), newOperator); - assertEq(_bridgeManager.getGovernorOf(newOperator), _caller); - - vm.expectRevert(abi.encodeWithSelector(IBridgeManager.ErrOperatorNotFound.selector, prevOperator)); - _bridgeManager.getGovernorOf(prevOperator); - } -} diff --git a/test/bridge/unit/concrete/bridge-manager/update/update.tree b/test/bridge/unit/concrete/bridge-manager/update/update.tree deleted file mode 100644 index 4394adec..00000000 --- a/test/bridge/unit/concrete/bridge-manager/update/update.tree +++ /dev/null @@ -1,20 +0,0 @@ -update.t.sol -├── when not call by the governor whose operator is being updated -│ └── it should revert -└── when call by the governor whose operator is being updated - ├── when the new operator is zero address - │ └── it should revert - ├── when the new operator is already existed in the current list of operators - │ └── it should revert - ├── when the new operator is already existed in the current list of governors - │ └── it should revert - ├── when the new operator is the same as the previous operator - │ └── it should revert - └── when the new operator is valid - ├── it should modify the current operators list - ├── it should remove the old operator - ├── it should notify the registers // TODO - ├── it should emit {BridgeOperatorUpdated} event - ├── it should then return new operator when query mapping by governor - ├── it should then return governor when query mapping by the new operator - └── it should then return address zero when query mapping by the old operator \ No newline at end of file diff --git a/test/bridge/unit/concrete/bridge-reward/BridgeReward.t.sol b/test/bridge/unit/concrete/bridge-reward/BridgeReward.t.sol deleted file mode 100644 index 529ae34f..00000000 --- a/test/bridge/unit/concrete/bridge-reward/BridgeReward.t.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { Base_Test } from "@ronin/test/Base.t.sol"; - -import { TransparentUpgradeableProxyV2 } from "@ronin/contracts/extensions/TransparentUpgradeableProxyV2.sol"; -import { IBridgeTracking } from "@ronin/contracts/interfaces/bridge/IBridgeTracking.sol"; -import { IBridgeManager } from "@ronin/contracts/interfaces/bridge/IBridgeManager.sol"; -import { IBridgeReward } from "@ronin/contracts/interfaces/bridge/IBridgeReward.sol"; -import { IBridgeSlash } from "@ronin/contracts/interfaces/bridge/IBridgeSlash.sol"; - -import { BridgeReward } from "@ronin/contracts/ronin/gateway/BridgeReward.sol"; - -import { MockBridgeTracking } from "@ronin/test/mocks/MockBridgeTracking.sol"; -import { MockBridgeManager } from "@ronin/test/mocks/MockBridgeManager.sol"; -import { MockBridgeSlash } from "@ronin/test/mocks/MockBridgeSlash.sol"; -import { MockValidatorSet_ForFoundryTest } from "@ronin/test/mocks/MockValidatorSet_ForFoundryTest.sol"; -import { Users } from "@ronin/test/utils/Types.sol"; - -contract BridgeReward_Unit_Concrete_Test is Base_Test { - BridgeReward internal _bridgeReward; - address internal _proxyAdmin; - uint256 internal _rewardPerPeriod; - - IBridgeTracking internal _bridgeTracking; - IBridgeManager internal _bridgeManager; - IBridgeSlash internal _bridgeSlash; - MockValidatorSet_ForFoundryTest internal _validatorSetContract; - - Users internal _users; - - function setUp() public virtual { - // Create users for testing. - _users = Users({ alice: createUser("Alice") }); - - _proxyAdmin = vm.addr(1); - _rewardPerPeriod = 50_000; - - address bridgeRewardImpl = address(new BridgeReward()); - - // Deploy the dependencies and mocks for testing contract - _bridgeReward = BridgeReward( - address( - new TransparentUpgradeableProxyV2{ value: _rewardPerPeriod * 1_000_000 }(bridgeRewardImpl, _proxyAdmin, "") - ) - ); - _bridgeTracking = new MockBridgeTracking(); - _bridgeManager = new MockBridgeManager(); - _bridgeSlash = new MockBridgeSlash(); - _validatorSetContract = new MockValidatorSet_ForFoundryTest(); - - _validatorSetContract.setCurrentPeriod(1337); - - // Initialize current on testing contract - _bridgeReward.initialize({ - bridgeManagerContract: address(_bridgeManager), - bridgeTrackingContract: address(_bridgeTracking), - bridgeSlashContract: address(_bridgeSlash), - validatorSetContract: address(_validatorSetContract), - dposGA: makeAccount("dposGA").addr, - rewardPerPeriod: _rewardPerPeriod - }); - - vm.prank(makeAccount("dposGA").addr); - _bridgeReward.initializeREP2(); - - // Label the base test contracts. - vm.label({ account: address(_bridgeReward), newLabel: "Bridge Reward" }); - vm.label({ account: address(_bridgeManager), newLabel: "Bridge Manager" }); - vm.label({ account: address(_bridgeTracking), newLabel: "Bridge Tracking" }); - vm.label({ account: address(_bridgeSlash), newLabel: "Bridge Slash" }); - vm.label({ account: address(_validatorSetContract), newLabel: "Validator Set Contract" }); - vm.label({ account: address(_proxyAdmin), newLabel: "Proxy Admin" }); - } - - /// @dev Generates a user, labels its address, and funds it with test assets. - function createUser(string memory name) internal returns (address payable) { - address payable user = payable(makeAddr(name)); - vm.deal({ account: user, newBalance: 100 ether }); - return user; - } -} diff --git a/test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.t.sol b/test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.t.sol deleted file mode 100644 index c6e5794a..00000000 --- a/test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.t.sol +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity >=0.8.17 <0.9.0; - -import { console2 } from "forge-std/console2.sol"; -import { StdStyle } from "forge-std/StdStyle.sol"; - -import "@ronin/contracts/utils/CommonErrors.sol"; -import { ContractType } from "@ronin/contracts/utils/ContractType.sol"; -import { IBridgeReward } from "@ronin/contracts/interfaces/bridge/IBridgeReward.sol"; -import { IBridgeRewardEvents } from "@ronin/contracts/interfaces/bridge/events/IBridgeRewardEvents.sol"; -import { BridgeReward } from "@ronin/contracts/ronin/gateway/BridgeReward.sol"; -import { BridgeTrackingHelper } from "@ronin/contracts/extensions/bridge-operator-governance/BridgeTrackingHelper.sol"; - -import { BridgeReward_Unit_Concrete_Test } from "../BridgeReward.t.sol"; - -contract Add_Unit_Concrete_Test is - BridgeReward_Unit_Concrete_Test, - IBridgeRewardEvents, - BridgeTrackingHelper // Need to inherits this to access event -{ - function setUp() public virtual override { - BridgeReward_Unit_Concrete_Test.setUp(); - vm.startPrank({ msgSender: address(_bridgeTracking) }); - } - - function test_RevertWhen_NotCalledByBridgeTracking() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - - uint256 period = _validatorSetContract.currentPeriod() + 1; - - changePrank(_users.alice); - vm.expectRevert( - abi.encodeWithSelector( - ErrUnexpectedInternalCall.selector, - IBridgeReward.execSyncReward.selector, - ContractType.BRIDGE_TRACKING, - _users.alice - ) - ); - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - } - - function test_RevertWhen_OperatorsLengthIsZero() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod() + 1; - - assembly ("memory-safe") { - mstore(operators, 0) - mstore(ballots, 0) - } - - // TODO: test tx not emit event - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - } - - function test_RevertWhen_TwoInputArraysLengthsDiffer() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod() + 1; - - assembly ("memory-safe") { - mstore(operators, 1) - } - - vm.expectRevert(abi.encodeWithSelector(ErrLengthMismatch.selector, IBridgeReward.execSyncReward.selector)); - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - - assembly ("memory-safe") { - mstore(operators, 0) - } - vm.expectRevert(abi.encodeWithSelector(ErrLengthMismatch.selector, IBridgeReward.execSyncReward.selector)); - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - } - - function test_RevertWhen_AlreadyRewardedPeriod() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod() - 1; - - vm.expectRevert(abi.encodeWithSelector(ErrInvalidArguments.selector, IBridgeReward.execSyncReward.selector)); - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - } - - function test_RevertWhen_PeriodTooFar() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 latestPeriod = _validatorSetContract.currentPeriod() - 1; - uint256 requestingPeriod = latestPeriod + 10; - - vm.expectRevert(abi.encodeWithSelector(ErrSyncTooFarPeriod.selector, requestingPeriod, latestPeriod)); - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: requestingPeriod - }); - } - - function test_execSyncReward_ShareEqually_WhenDataCorrupts_NotTopUpFund() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod(); - - ballots[0] = 100_000; - - // Set balance of bridge reward to zero - vm.deal({ account: address(_bridgeReward), newBalance: 0 }); - - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeTrackingIncorrectlyResponded(); - for (uint i; i < operators.length; i++) { - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeRewardScatterFailed(period, operators[i], _rewardPerPeriod / operators.length); - } - - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - - assertEq(_bridgeReward.getLatestRewardedPeriod(), period); - } - - function test_execSyncReward_ShareEqually_WhenDataCorrupts_HaveEnoughFund_OneAbnormalBallot() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod(); - - ballots[0] = 100_000; - - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeTrackingIncorrectlyResponded(); - for (uint i; i < operators.length; i++) { - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeRewardScattered(period, operators[i], _rewardPerPeriod / operators.length); - } - - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - assertEq(_bridgeReward.getLatestRewardedPeriod(), period); - } - - function test_execSyncReward_ShareEqually_WhenDataCorrupts_HaveEnoughFund_AbnormalTotalBallot() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod(); - - // Reduce number of total ballot - totalBallot -= 1; - - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeTrackingIncorrectlyResponded(); - for (uint i; i < operators.length; i++) { - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeRewardScattered(period, operators[i], _rewardPerPeriod / operators.length); - } - - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - } - - function test_execSyncReward_ShareEqually_WhenNoVote() external { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod(); - - ballots[0] = 0; - ballots[1] = 0; - ballots[2] = 0; - ballots[3] = 0; - totalBallot = 0; - totalVote = 100; - - for (uint i; i < operators.length; i++) { - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeRewardScattered(period, operators[i], _rewardPerPeriod / operators.length); - } - - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - assertEq(_bridgeReward.getLatestRewardedPeriod(), period); - } - - function test_execSyncReward_SharePropotionally() public { - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod(); - - for (uint i; i < operators.length; i++) { - vm.expectEmit({ emitter: address(_bridgeReward) }); - emit BridgeRewardScattered(period, operators[i], (_rewardPerPeriod * ballots[i]) / totalBallot); - } - - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - assertEq(_bridgeReward.getLatestRewardedPeriod(), period); - } - - function test_RevertWhen_SharePropotionally_ThenShareAgain() external { - test_execSyncReward_SharePropotionally(); - - ( - address[] memory operators, - uint256[] memory ballots, - uint256 totalBallot, - uint256 totalVote - ) = _generateInput_execSyncReward(); - uint256 period = _validatorSetContract.currentPeriod(); - vm.expectRevert(abi.encodeWithSelector(ErrInvalidArguments.selector, IBridgeReward.execSyncReward.selector)); - _bridgeReward.execSyncReward({ - operators: operators, - ballots: ballots, - totalBallot: totalBallot, - totalVote: totalVote, - period: period - }); - } - - function _generateInput_execSyncReward() - internal - pure - returns (address[] memory operators, uint256[] memory ballots, uint256 totalBallot, uint256 totalVote) - { - operators = new address[](4); - operators[0] = address(0x10000); - operators[1] = address(0x10001); - operators[2] = address(0x10002); - operators[3] = address(0x10003); - - ballots = new uint256[](4); - ballots[0] = 10; - ballots[1] = 20; - ballots[2] = 30; - ballots[3] = 40; - - totalBallot = 100; - totalVote = 40; - } -} diff --git a/test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.tree b/test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.tree deleted file mode 100644 index f02d00b7..00000000 --- a/test/bridge/unit/concrete/bridge-reward/execSyncReward/execSyncReward.tree +++ /dev/null @@ -1,26 +0,0 @@ -execSyncReward.t.sol -├── when not called by BridgeTracking -│ └── it should revert -└── when call by BridgeTracking - ├── when operators length is zero - │ └── it should revert - ├── when operators and ballots length mismatchs - │ └── it should revert - ├── when period number is less than {latestRewardedPeriod + 1} - │ └── it should revert - ├── when period number is greater than {latestRewardedPeriod + 1} - │ └── it should revert with too far period - └── when input length valid - ├── when data corrupts - │ ├── when reward contract insufficient funds - │ │ ├── should share reward equally - │ │ └── should emit fail transfer event - │ └── when reward contract have funds - │ ├── should share reward equally - │ └── should emit success transfer event - ├── when there is no vote - │ └── should share reward equally - └── when data is normal - ├── should share reward proportionally - └── when call execSyncReward again - └── should revert with already rewarded or invalid arguments \ No newline at end of file diff --git a/test/bridge/unit/fuzz/bridge-manager/BridgeManagerCRUD.t.sol b/test/bridge/unit/fuzz/bridge-manager/BridgeManagerCRUD.t.sol deleted file mode 100644 index e8ed23f0..00000000 --- a/test/bridge/unit/fuzz/bridge-manager/BridgeManagerCRUD.t.sol +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { console } from "forge-std/console.sol"; -import { IBridgeManager, BridgeManagerUtils } from "../utils/BridgeManagerUtils.t.sol"; -import { RoninGatewayV3 } from "@ronin/contracts/ronin/gateway/RoninGatewayV3.sol"; -import { RoleAccess, ContractType, AddressArrayUtils, MockBridgeManager } from "@ronin/contracts/mocks/ronin/MockBridgeManager.sol"; -import { ErrBridgeOperatorUpdateFailed, ErrBridgeOperatorAlreadyExisted, ErrUnauthorized, ErrInvalidVoteWeight, ErrZeroAddress, ErrUnexpectedInternalCall } from "@ronin/contracts/utils/CommonErrors.sol"; - -contract BridgeManagerCRUDTest is BridgeManagerUtils { - using AddressArrayUtils for address[]; - - enum InputIndex { - VoteWeights, - Governors, - BridgeOperators - } - - address internal _bridgeManager; - - function setUp() external { - _setUp(); - _label(); - } - - function testFail_MaliciousUpdateBridgeOperator() external { - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs( - DEFAULT_R1, - DEFAULT_R2, - DEFAULT_R3, - DEFAULT_NUM_BRIDGE_OPERATORS - ); - _bridgeManager = address(new MockBridgeManager(bridgeOperators, governors, voteWeights)); - MockBridgeManager bridgeManager = MockBridgeManager(_bridgeManager); - - vm.startPrank(governors[0]); - address lastOperator; - - for (uint256 i = 1; i < bridgeOperators.length; ++i) { - lastOperator = bridgeOperators[i]; - bridgeManager.updateBridgeOperator(bridgeOperators[0], lastOperator); - vm.expectRevert(abi.encodeWithSelector(ErrBridgeOperatorUpdateFailed.selector, lastOperator)); - } - - vm.stopPrank(); - } - - /** - * @notice Checks whether unauthorized caller except bridge contract can add bridge operators. - */ - function testFail_AddBridgeOperators_CallerNotBridgeAdminOperator( - address caller, - uint256 r1, - uint256 r2, - uint256 r3, - uint256 numBridgeOperators - ) external virtual { - vm.assume(caller != _bridgeManager); - - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs(r1, r2, r3, numBridgeOperators); - - vm.expectRevert( - abi.encodeWithSelector(ErrUnexpectedInternalCall.selector, IBridgeManager.addBridgeOperators.selector, ContractType.BRIDGE, caller) - ); - - _addBridgeOperators(caller, _bridgeManager, voteWeights, governors, bridgeOperators); - } - - /** - * @notice Checks whether bridge contract can add bridge operators. - */ - function test_AddBridgeOperators_CallerIsBridgeAdminOperator(uint256 r1, uint256 r2, uint256 r3, uint256 numBridgeOperators) external virtual { - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs(r1, r2, r3, numBridgeOperators); - - IBridgeManager bridgeManager = _addBridgeOperators(_bridgeManager, _bridgeManager, voteWeights, governors, bridgeOperators); - - _invariantTest(bridgeManager, voteWeights, governors, bridgeOperators); - } - - /** - * @notice Checks whether bridge contract can add bridge operators - * when governors, operators or vote weight contains null or duplicated. - */ - function testFail_AddBridgeOperators_NullOrDuplicateInputs(uint256 r1, uint256 r2, uint256 r3, uint256 numBridgeOperators) external virtual { - ( - bool nullifyOrDuplicate, - uint256 modifyTimes, - uint256 modifiedInputIdx, - uint96[] memory voteWeights, - address[] memory governors, - address[] memory bridgeOperators - ) = _nullOrDuplicateInputs(r1, r2, r3, numBridgeOperators); - - if (modifiedInputIdx == uint8(InputIndex.VoteWeights)) { - // allow duplicate vote weights - vm.assume(nullifyOrDuplicate); - vm.expectRevert(abi.encodeWithSelector(ErrInvalidVoteWeight.selector, IBridgeManager.addBridgeOperators.selector)); - } else { - if (modifyTimes == 1) { - vm.expectRevert(abi.encodeWithSelector(ErrZeroAddress.selector, IBridgeManager.addBridgeOperators.selector)); - } else { - vm.expectRevert(abi.encodeWithSelector(AddressArrayUtils.ErrDuplicated.selector, IBridgeManager.addBridgeOperators.selector)); - } - } - - _addBridgeOperators(_bridgeManager, _bridgeManager, voteWeights, governors, bridgeOperators); - } - - /** - * @notice Checks whether bridge contract can remove bridge operators. - */ - function test_RemoveBridgeOperators_CallerIsBridgeContract(uint256 r1, uint256 r2, uint256 r3, uint16 numBridgeOperators) external virtual { - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs(r1, r2, r3, numBridgeOperators); - - IBridgeManager bridgeManager = _addBridgeOperators(_bridgeManager, _bridgeManager, voteWeights, governors, bridgeOperators); - uint256 removeAmount = _randomize(voteWeights.length, 1, voteWeights.length); - - uint256 tailIdx = voteWeights.length - 1; - uint256 r = _randomize(_triShuffle(r1, r2, r3), 0, tailIdx); - address[] memory removeBridgeOperators = new address[](removeAmount); - for (uint256 i; i < removeAmount; ) { - r = _randomize(r, 0, tailIdx); - - governors[r] = governors[tailIdx]; - voteWeights[r] = voteWeights[tailIdx]; - removeBridgeOperators[i] = bridgeOperators[r]; - bridgeOperators[r] = bridgeOperators[tailIdx]; - - unchecked { - ++i; - --tailIdx; - } - } - - uint256 remainLength = voteWeights.length - removeAmount; - assembly { - mstore(governors, remainLength) - mstore(voteWeights, remainLength) - mstore(bridgeOperators, remainLength) - } - - vm.prank(_bridgeManager); - vm.expectEmit(_bridgeManager); - bool[] memory statuses; - uint256[] memory tmp = _createRandomNumbers(0, removeBridgeOperators.length, 1, 1); - assembly { - statuses := tmp - } - emit BridgeOperatorsRemoved(statuses, removeBridgeOperators); - bridgeManager.removeBridgeOperators(removeBridgeOperators); - - _invariantTest(bridgeManager, voteWeights, governors, bridgeOperators); - } - - /** - * @notice Checks whether governor can update their bridge operator address. - */ - function test_UpdateBridgeOperator_CallerIsGovernor(uint256 r1, uint256 r2, uint256 r3, uint16 numBridgeOperators) external virtual { - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs(r1, r2, r3, numBridgeOperators); - IBridgeManager bridgeManager = _addBridgeOperators(_bridgeManager, _bridgeManager, voteWeights, governors, bridgeOperators); - - uint256 randomSeed = _randomize(_triShuffle(r1, r2, r3), 0, voteWeights.length - 1); - address randomGovernor = governors[randomSeed]; - address correspondingOperator = bridgeOperators[randomSeed]; - address newBridgeOperator = makeAddr("NEW_BRIDGE_OPERATOR"); - vm.deal(newBridgeOperator, 1 ether); - - vm.prank(randomGovernor); - vm.expectEmit(_bridgeManager); - bool[] memory statuses = new bool[](1); - statuses[0] = true; - emit BridgeOperatorUpdated(randomGovernor, bridgeOperators[randomSeed], newBridgeOperator); - bridgeManager.updateBridgeOperator(correspondingOperator, newBridgeOperator); - - // swap and pop - bridgeOperators[randomSeed] = bridgeOperators[bridgeOperators.length - 1]; - bridgeOperators[bridgeOperators.length - 1] = newBridgeOperator; - - _invariantTest(bridgeManager, voteWeights, governors, bridgeOperators); - } - - /** - * @notice Checks whether unauthorized sender can update bridge operator address. - */ - function testFail_UpdateBridgeOperator_CallerIsNotGovernor(uint256 r1, uint256 r2, uint256 r3, uint16 numBridgeOperators) external virtual { - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs(r1, r2, r3, numBridgeOperators); - IBridgeManager bridgeManager = _addBridgeOperators(_bridgeManager, _bridgeManager, voteWeights, governors, bridgeOperators); - - address unauthorizedCaller = makeAddr("UNAUTHORIZED_CALLER"); - for (uint256 i; i < governors.length; ) { - vm.assume(unauthorizedCaller != governors[i]); - unchecked { - ++i; - } - } - address newBridgeOperator = makeAddr("NEW_BRIDGE_OPERATOR"); - - vm.prank(unauthorizedCaller); - bridgeManager.updateBridgeOperator(bridgeOperators[0], newBridgeOperator); - - vm.expectRevert(abi.encodeWithSelector(ErrUnauthorized.selector, IBridgeManager.updateBridgeOperator.selector, RoleAccess.GOVERNOR)); - } - - function _setUp() internal virtual { - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs( - DEFAULT_R1, - DEFAULT_R2, - DEFAULT_R3, - DEFAULT_NUM_BRIDGE_OPERATORS - ); - _bridgeManager = address(new MockBridgeManager(bridgeOperators, governors, voteWeights)); - - // empty storage for testing - vm.prank(_bridgeManager); - IBridgeManager(_bridgeManager).removeBridgeOperators(bridgeOperators); - } - - function _label() internal virtual { - vm.label(_bridgeManager, "BRIDGE_ADMIN_OPERATOR"); - } -} diff --git a/test/bridge/unit/fuzz/bridge-manager/BridgeReward.t.sol b/test/bridge/unit/fuzz/bridge-manager/BridgeReward.t.sol deleted file mode 100644 index 95f33eb3..00000000 --- a/test/bridge/unit/fuzz/bridge-manager/BridgeReward.t.sol +++ /dev/null @@ -1,274 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { console } from "forge-std/console.sol"; -import { Base_Test } from "@ronin/test/Base.t.sol"; -import { LibArrayUtils } from "@ronin/test/helpers/LibArrayUtils.t.sol"; -import { IBridgeRewardEvents } from "@ronin/contracts/interfaces/bridge/events/IBridgeRewardEvents.sol"; -import { IBridgeManager, BridgeManagerUtils } from "../utils/BridgeManagerUtils.t.sol"; -import { MockValidatorContract_OnlyTiming_ForHardhatTest } from "@ronin/contracts/mocks/ronin/MockValidatorContract_OnlyTiming_ForHardhatTest.sol"; -import { BridgeTracking } from "@ronin/contracts/ronin/gateway/BridgeTracking.sol"; -import { BridgeReward } from "@ronin/contracts/ronin/gateway/BridgeReward.sol"; -import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import { RoleAccess, ContractType, AddressArrayUtils, MockBridgeManager } from "@ronin/contracts/mocks/ronin/MockBridgeManager.sol"; -import { IBridgeSlash, MockBridgeSlash, BridgeSlash } from "@ronin/contracts/mocks/ronin/MockBridgeSlash.sol"; -import { IBridgeReward, MockBridgeReward, BridgeReward } from "@ronin/contracts/mocks/ronin/MockBridgeReward.sol"; - -contract BridgeRewardTest is Base_Test, IBridgeRewardEvents, BridgeManagerUtils { - using LibArrayUtils for uint256[]; - - uint256 internal constant DEFAULT_REWARD_PER_PERIOD = 1 ether; - - address internal _admin; - address internal _validatorContract; - address internal _bridgeRewardLogic; - address internal _bridgeManagerContract; - address internal _bridgeRewardContract; - address internal _bridgeSlashLogic; - address internal _bridgeSlashContract; - address internal _bridgeTrackingContract; - address internal _bridgeTrackingLogic; - - bytes internal _defaultBridgeManagerInputs; - - function setUp() external { - _setUp(); - _label(); - } - - /** - * @notice Test the fuzz reward calculation logic. - * @param r1 Random number for generating slashUntils. - * @param r2 Random number for generating ballots. - * @param totalVote Total number of votes. - * @param period The period being tested. - */ - function test_Fuzz_RewardCalculationLogic(uint256 r1, uint256 r2, uint256 totalVote, uint256 period) external { - // Ensure r1 and r2 are not equal - vm.assume(r1 != r2); - - // Bound the period within the valid range - period = _bound(period, 1, type(uint64).max); - - // Decode the default bridge manager inputs - (address[] memory bridgeOperators, , ) = abi.decode(_defaultBridgeManagerInputs, (address[], address[], uint256[])); - - // Generate random numbers for slashUntils and ballots - uint256[] memory slashUntils = _createRandomNumbers(r1, bridgeOperators.length, 0, MAX_FUZZ_INPUTS); - uint256[] memory ballots = _createRandomNumbers(r2, bridgeOperators.length, 0, MAX_FUZZ_INPUTS); - - // Get the bridge reward contract instance - MockBridgeReward bridgeRewardContract = MockBridgeReward(payable(_bridgeRewardContract)); - - // Calculate the total number of ballots - uint256 totalBallot = ballots.sum(); - // Determine if the reward should be shared equally among bridge operators - bool shouldShareEqually = bridgeRewardContract.shouldShareEqually(totalBallot, totalVote, ballots); - - // Get the reward per period from the bridge reward contract - uint256 rewardPerPeriod = IBridgeReward(_bridgeRewardContract).getRewardPerPeriod(); - - // Assert the reward calculation based on the sharing method - if (shouldShareEqually) { - _assertCalculateRewardEqually(shouldShareEqually, rewardPerPeriod, totalBallot, bridgeRewardContract, ballots); - } else { - _assertCalculateRewardProportionally( - shouldShareEqually, - rewardPerPeriod, - totalBallot, - bridgeRewardContract, - ballots - ); - } - // Assert the slashing of bridge operators for the given period - _assertSlashBridgeOperators(period, slashUntils, bridgeRewardContract); - } - - /** - * @notice Test the scenario when the total number of ballots is zero and the bridge tracking response is not valid. - * @dev This function is for internal testing purposes only. - * @param totalVote Total number of votes. - */ - function test_WhenTotalBallotsZero_NotValidBridgeTrackingResponse(uint256 totalVote) external { - // Get the bridge reward contract instance - MockBridgeReward bridgeRewardContract = MockBridgeReward(payable(_bridgeRewardContract)); - - // Decode the default bridge manager inputs - (address[] memory bridgeOperators, , ) = abi.decode(_defaultBridgeManagerInputs, (address[], address[], uint256[])); - // Create an empty array for ballots - uint256[] memory ballots = new uint256[](bridgeOperators.length); - // Calculate the total number of ballots - uint256 totalBallot = ballots.sum(); - - // Check if the bridge tracking response is valid and if the reward should be shared equally - bool isValidResponse = bridgeRewardContract.isValidBridgeTrackingResponse(totalBallot, totalVote, ballots); - bool shouldShareEqually = bridgeRewardContract.shouldShareEqually(totalBallot, totalVote, ballots); - - // Assert that the bridge tracking response is not valid and the reward is shared equally - assertTrue(isValidResponse); - assertTrue(shouldShareEqually); - } - - /** - * @notice Asserts the calculation of rewards proportionally. - * @param isShareEqually Flag indicating whether rewards are shared equally. - * @param rewardPerPeriod The total reward amount per period. - * @param totalBallot The total number of ballots. - * @param bridgeRewardContract The mock bridge reward contract. - * @param ballots The array of ballots for bridge operators. - */ - function _assertCalculateRewardProportionally( - bool isShareEqually, - uint256 rewardPerPeriod, - uint256 totalBallot, - MockBridgeReward bridgeRewardContract, - uint256[] memory ballots - ) internal { - // Assert that rewards are not shared equally - assertFalse(isShareEqually); - - uint256 length = ballots.length; - uint256 actual; - uint256 expected; - - for (uint256 i; i < length; ) { - console.log("actual", actual); - console.log("expected", expected); - - // Calculate the actual and expected rewards - actual = bridgeRewardContract.calcReward(isShareEqually, length, rewardPerPeriod, ballots[i], totalBallot); - expected = (rewardPerPeriod * ballots[i]) / totalBallot; - - // Assert that the actual and expected rewards are equal - assertTrue(actual == expected); - - unchecked { - ++i; - } - } - } - - /** - * @notice Asserts the calculation of rewards when shared equally. - * @param shouldShareEqually Flag indicating whether rewards are shared equally. - * @param rewardPerPeriod The total reward amount per period. - * @param totalBallot The total number of ballots. - * @param bridgeRewardContract The mock bridge reward contract. - * @param ballots The array of ballots for bridge operators. - */ - function _assertCalculateRewardEqually( - bool shouldShareEqually, - uint256 rewardPerPeriod, - uint256 totalBallot, - MockBridgeReward bridgeRewardContract, - uint256[] memory ballots - ) internal { - // Assert that rewards are shared equally - assertTrue(shouldShareEqually); - uint256 actual; - uint256 length = ballots.length; - uint256 expected = rewardPerPeriod / length; - - for (uint256 i; i < length; ) { - console.log("actual", actual); - console.log("expected", expected); - - // Calculate the actual and expected rewards - actual = bridgeRewardContract.calcReward(shouldShareEqually, length, rewardPerPeriod, ballots[i], totalBallot); - // Assert that the actual reward is equal to the expected reward - assertTrue(actual == expected); - - unchecked { - ++i; - } - } - } - - /** - * @notice Asserts the slashing of bridge operators for a given period. - * @param period The period being tested. - * @param slashUntils The array of slash until periods for bridge operators. - * @param bridgeRewardContract The mock bridge reward contract. - */ - function _assertSlashBridgeOperators( - uint256 period, - uint256[] memory slashUntils, - MockBridgeReward bridgeRewardContract - ) internal { - uint256 length = slashUntils.length; - for (uint256 i; i < length; ) { - // Check if the bridge operator is slashed for the current period - if (period <= slashUntils[i]) { - // Assert that the bridge operator is slashed for the current period - assertTrue(bridgeRewardContract.shouldSlashedThisPeriod(period, slashUntils[i])); - } - - unchecked { - ++i; - } - } - } - - function _setUp() internal virtual { - _admin = vm.addr(1); - - _validatorContract = address(new MockValidatorContract_OnlyTiming_ForHardhatTest(200)); - - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs( - DEFAULT_R1, - DEFAULT_R2, - DEFAULT_R3, - DEFAULT_NUM_BRIDGE_OPERATORS - ); - - _defaultBridgeManagerInputs = abi.encode(bridgeOperators, governors, voteWeights); - - _bridgeManagerContract = address(new MockBridgeManager(bridgeOperators, governors, voteWeights)); - - _bridgeTrackingLogic = address(new BridgeTracking()); - _bridgeTrackingContract = address(new TransparentUpgradeableProxy(_bridgeTrackingLogic, _admin, "")); - - _bridgeSlashLogic = address(new MockBridgeSlash()); - _bridgeSlashContract = address( - new TransparentUpgradeableProxy( - _bridgeSlashLogic, - _admin, - abi.encodeCall( - BridgeSlash.initialize, - (_validatorContract, _bridgeManagerContract, _bridgeTrackingContract, address(0)) - ) - ) - ); - - _bridgeRewardLogic = address(new MockBridgeReward()); - _bridgeRewardContract = address( - new TransparentUpgradeableProxy( - _bridgeRewardLogic, - _admin, - abi.encodeCall( - BridgeReward.initialize, - ( - _bridgeManagerContract, - _bridgeTrackingContract, - _bridgeSlashContract, - _validatorContract, - address(0), - DEFAULT_REWARD_PER_PERIOD - ) - ) - ) - ); - } - - function _label() internal virtual { - vm.label(_admin, "ADMIN"); - vm.label(_validatorContract, "VALIDATOR"); - vm.label(_bridgeManagerContract, "BRIDGE_MANAGER"); - vm.label(_bridgeTrackingLogic, "BRIDGE_TRACKING_LOGIC"); - vm.label(_bridgeTrackingContract, "BRIDGE_TRACKING"); - vm.label(_bridgeSlashLogic, "BRIDGE_SLASH_LOGIC"); - vm.label(_bridgeSlashContract, "BRIDGE_SLASH"); - vm.label(_bridgeRewardLogic, "BRIDGE_REWARD_LOGIC"); - vm.label(_bridgeRewardContract, "BRIDGE_REWARD_CONTRACT"); - } -} diff --git a/test/bridge/unit/fuzz/bridge-manager/BridgeSlash.t.sol b/test/bridge/unit/fuzz/bridge-manager/BridgeSlash.t.sol deleted file mode 100644 index b166af7b..00000000 --- a/test/bridge/unit/fuzz/bridge-manager/BridgeSlash.t.sol +++ /dev/null @@ -1,334 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import { console } from "forge-std/console.sol"; -import { Test } from "forge-std/Test.sol"; -import { LibArrayUtils } from "@ronin/test/helpers/LibArrayUtils.t.sol"; -import { TransparentUpgradeableProxyV2 } from "@ronin/contracts/extensions/TransparentUpgradeableProxyV2.sol"; -import { RoninGatewayV3 } from "@ronin/contracts/ronin/gateway/RoninGatewayV3.sol"; -import { MockValidatorSet_ForFoundryTest } from "../../../../mocks/MockValidatorSet_ForFoundryTest.sol"; -import { BridgeTracking } from "@ronin/contracts/ronin/gateway/BridgeTracking.sol"; -import { IBridgeSlash, MockBridgeSlash, BridgeSlash } from "@ronin/contracts/mocks/ronin/MockBridgeSlash.sol"; -import { IBridgeManager, BridgeManagerUtils } from "../utils/BridgeManagerUtils.t.sol"; -import { RoninBridgeManager } from "@ronin/contracts/ronin/gateway/RoninBridgeManager.sol"; -import { Math } from "@ronin/contracts/libraries/Math.sol"; -import { RoleAccess, ContractType, AddressArrayUtils, MockBridgeManager } from "@ronin/contracts/mocks/ronin/MockBridgeManager.sol"; -import { ErrProxyCallFailed, ErrorHandler } from "@ronin/contracts/libraries/ErrorHandler.sol"; -import { IBridgeSlashEvents } from "@ronin/contracts/interfaces/bridge/events/IBridgeSlashEvents.sol"; - -contract BridgeSlashTest is IBridgeSlashEvents, BridgeManagerUtils { - using ErrorHandler for bool; - using LibArrayUtils for *; - using AddressArrayUtils for *; - - uint256 internal constant MIN_PERIOD_DURATION = 1; - uint256 internal constant MAX_PERIOD_DURATION = 20; - - /// @dev immutable contracts - address internal _admin; - address internal _validatorContract; - address internal _bridgeManagerContract; - /// @dev proxy contracts - address internal _gatewayLogic; - address internal _gatewayContract; - address internal _bridgeSlashLogic; - address internal _bridgeSlashContract; - address internal _bridgeTrackingLogic; - address internal _bridgeTrackingContract; - - bytes internal _defaultBridgeManagerInputs; - - function setUp() external { - _setUp(); - _label(); - } - - /** - * @notice Tests the fuzz slash tier logic by simulating the slash calculation for a given ballot and total ballots. - * @dev This function is for testing purposes only. - * @param ballot The number of ballots for the specific bridge operator. - * @param totalVote The total number of votes for the period. - * @param period The current period. - * @param slashUntilPeriod The slash until period for the bridge operator. - */ - function test_Fuzz_SlashTierLogic(uint96 ballot, uint96 totalVote, uint64 period, uint64 slashUntilPeriod) external { - // Assume period is not zero and totalVote is not zero, and ballot is less than totalVote - vm.assume(period != 0); - vm.assume(totalVote >= IBridgeSlash(_bridgeSlashContract).MINIMUM_VOTE_THRESHOLD() && ballot < totalVote); - - // Get the bridge slash contract and determine the slash tier - IBridgeSlash bridgeSlashContract = IBridgeSlash(_bridgeSlashContract); - IBridgeSlash.Tier tier = bridgeSlashContract.getSlashTier(ballot, totalVote); - // Calculate the new slash until period using the mock bridge slash contract - uint256 newSlashUntilPeriod = MockBridgeSlash(payable(_bridgeSlashContract)).calcSlashUntilPeriod( - tier, - period, - slashUntilPeriod - ); - - // Log the tier and slash period information - console.log("tier", "period", "slashUntilPeriod", "newSlashUntilPeriod"); - console.log(uint8(tier), period, slashUntilPeriod, newSlashUntilPeriod); - - if (tier == Tier.Tier1) { - // Check the slash duration for Tier 1 - if (period <= slashUntilPeriod) { - assertTrue(newSlashUntilPeriod == uint256(slashUntilPeriod) + bridgeSlashContract.TIER_1_PENALTY_DURATION()); - } else { - assertTrue(newSlashUntilPeriod == period + bridgeSlashContract.TIER_1_PENALTY_DURATION() - 1); - } - } else if (tier == Tier.Tier2) { - // Check the slash duration for Tier 2 - if (period <= slashUntilPeriod) { - assertTrue(newSlashUntilPeriod == uint256(slashUntilPeriod) + bridgeSlashContract.TIER_2_PENALTY_DURATION()); - - // Check if the slash duration meets the removal threshold - if ( - MockBridgeSlash(payable(_bridgeSlashContract)).isSlashDurationMetRemovalThreshold(newSlashUntilPeriod, period) - ) { - assertTrue(newSlashUntilPeriod - period + 1 >= bridgeSlashContract.REMOVE_DURATION_THRESHOLD()); - } - } else { - assertTrue(newSlashUntilPeriod == uint256(period) + bridgeSlashContract.TIER_2_PENALTY_DURATION() - 1); - } - } - } - - /** - * @notice Tests the recording of events when bridge operators are added. - * @dev This function is for testing purposes only. - * @param r1 1st Random value for generating valid inputs. - * @param r2 2nd Random value for generating valid inputs. - * @param r3 3rd Random value for generating valid inputs. - * @param numBridgeOperators The number of bridge operators to add. - * @param period The current period. - */ - function test_bridgeSlash_recordEvents_onBridgeOperatorsAdded( - uint256 r1, - uint256 r2, - uint256 r3, - uint256 numBridgeOperators, - uint256 period - ) external { - address[] memory currentOperators = IBridgeManager(_bridgeManagerContract).getBridgeOperators(); - vm.prank(_bridgeManagerContract, _bridgeManagerContract); - IBridgeManager(_bridgeManagerContract).removeBridgeOperators(currentOperators); - // Assume the input values are not equal to the default values - vm.assume(r1 != DEFAULT_R1 && r2 != DEFAULT_R2 && r3 != DEFAULT_R3); - // Bound the period between 1 and the maximum value of uint64 - period = _bound(period, 1, type(uint64).max); - - // Set the current period in the mock validator contract - MockValidatorSet_ForFoundryTest(payable(_validatorContract)).setCurrentPeriod(period); - - // Register the bridge slash contract as a callback - vm.prank(_bridgeManagerContract, _bridgeManagerContract); - address[] memory registers = new address[](1); - registers[0] = _bridgeSlashContract; - MockBridgeManager(payable(_bridgeManagerContract)).registerCallbacks(registers); - - // Generate valid inputs for bridge operators - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs( - r1, - r2, - r3, - numBridgeOperators - ); - - _addBridgeOperators(_bridgeManagerContract, _bridgeManagerContract, voteWeights, governors, bridgeOperators); - - // Retrieve the added periods for the bridge operators - uint256[] memory addedPeriods = IBridgeSlash(_bridgeSlashContract).getAddedPeriodOf(bridgeOperators); - // Check that the added periods match the current period - for (uint256 i; i < addedPeriods.length; ) { - assertEq(addedPeriods[i], period); - unchecked { - ++i; - } - } - } - - /* - * @notice Tests the exclusion of newly added operators during the execution of slashBridgeOperators. - * @param 1st Random value for generating valid inputs. - * @param period The initial period. - * @param duration The duration of the test. - * @param newlyAddedSize The number of newly added operators. - */ - function test_ExcludeNewlyAddedOperators_ExecSlashBridgeOperators( - uint256 r1, - uint256 period, - uint256 duration, - uint256 newlyAddedSize - ) external { - vm.assume(r1 != 0); - vm.assume(r1 != DEFAULT_R1 && r1 != DEFAULT_R2 && r1 != DEFAULT_R3); - // Bound the period, duration, and newlyAddedSize values - period = _bound(period, 1, type(uint64).max); - duration = _bound(duration, MIN_PERIOD_DURATION, MAX_PERIOD_DURATION); - newlyAddedSize = _bound(newlyAddedSize, MIN_FUZZ_INPUTS, MAX_FUZZ_INPUTS); - - // Register the bridge slash contract as a callback in the bridge manager contract - address[] memory registers = new address[](1); - registers[0] = _bridgeSlashContract; - vm.prank(_bridgeManagerContract, _bridgeManagerContract); - MockBridgeManager(payable(_bridgeManagerContract)).registerCallbacks(registers); - - // Decode the default bridge manager inputs to retrieve bridge operators - (address[] memory bridgeOperators, , ) = abi.decode(_defaultBridgeManagerInputs, (address[], address[], uint256[])); - - for (uint256 i; i < duration; ) { - // Set the current period in the mock validator contract - MockValidatorSet_ForFoundryTest(payable(_validatorContract)).setCurrentPeriod(period); - // Generate valid inputs for newly added operators - uint256[] memory newlyAddedAtPeriods; - address[] memory newlyAddedOperators; - { - address[] memory newlyAddedGovernors; - uint96[] memory newlyAddedWeights; - (newlyAddedOperators, newlyAddedGovernors, newlyAddedWeights) = getValidInputs( - r1, - ~r1, - r1 << 1, - newlyAddedSize - ); - - // Add the newly added operators using the bridge manager contract - vm.prank(_bridgeManagerContract, _bridgeManagerContract); - bool[] memory addeds = IBridgeManager(_bridgeManagerContract).addBridgeOperators( - newlyAddedWeights, - newlyAddedGovernors, - newlyAddedOperators - ); - vm.assume(addeds.sum() == addeds.length); - // Retrieve the added periods for the newly added operators - newlyAddedAtPeriods = IBridgeSlash(_bridgeSlashContract).getAddedPeriodOf(newlyAddedOperators); - } - - // Generate random ballots for bridge operators and newly added operators - uint256[] memory ballots = _createRandomNumbers(r1, bridgeOperators.length + newlyAddedSize, 0, MAX_FUZZ_INPUTS); - // Execute slashBridgeOperators for all operators - vm.prank(_bridgeTrackingContract, _bridgeTrackingContract); - IBridgeSlash(_bridgeSlashContract).execSlashBridgeOperators( - bridgeOperators.extend(newlyAddedOperators), - ballots, - ballots.sum(), - ballots.sum(), - period - ); - - // Check that the slashUntilPeriods and newlyAddedAtPeriods are correctly set - uint256 length = newlyAddedAtPeriods.length; - uint256[] memory slashUntilPeriods = IBridgeSlash(_bridgeSlashContract).getSlashUntilPeriodOf( - newlyAddedOperators - ); - for (uint256 j; j < length; ) { - assertEq(slashUntilPeriods[j], 0); - assertEq(newlyAddedAtPeriods[j], period); - unchecked { - ++j; - } - } - - // Generate the next random number for r1 - r1 = uint256(keccak256(abi.encode(r1))); - - unchecked { - ++period; - ++i; - } - } - } - - /* - * @notice Tests the execution of `execSlashBridgeOperators` function with valid inputs. - * @param Random value for generating random numbers. - * @param period The initial period. - * @param duration The duration of the test. - */ - function test_Valid_ExecSlashBridgeOperators(uint256 r1, uint256 period, uint256 duration) external { - // Bound the period and duration values - period = _bound(period, 1, type(uint64).max); - duration = _bound(duration, MIN_PERIOD_DURATION, MAX_PERIOD_DURATION); - - // Decode the default bridge manager inputs to retrieve bridge operators - (address[] memory bridgeOperators, , ) = abi.decode(_defaultBridgeManagerInputs, (address[], address[], uint256[])); - - vm.startPrank(_bridgeTrackingContract, _bridgeTrackingContract); - uint256[] memory ballots; - uint256 totalBallotForPeriod; - IBridgeSlash bridgeSlashContract = IBridgeSlash(_bridgeSlashContract); - MockValidatorSet_ForFoundryTest validatorContract = MockValidatorSet_ForFoundryTest(payable(_validatorContract)); - for (uint256 i; i < duration; ) { - // Generate random ballots for bridge operators - ballots = _createRandomNumbers(r1, bridgeOperators.length, 0, MAX_FUZZ_INPUTS); - totalBallotForPeriod = ballots.sum(); - - // Set the current period in the mock validator contract - validatorContract.setCurrentPeriod(period); - - // Execute the `execSlashBridgeOperators` function - bridgeSlashContract.execSlashBridgeOperators( - bridgeOperators, - ballots, - totalBallotForPeriod, - totalBallotForPeriod, - period - ); - - // Generate the next random number for r1 using the keccak256 hash function - r1 = uint256(keccak256(abi.encode(r1))); - - unchecked { - ++period; - ++i; - } - } - vm.stopPrank(); - } - - function _setUp() internal virtual { - _admin = vm.addr(1); - _validatorContract = address(new MockValidatorSet_ForFoundryTest()); - (address[] memory bridgeOperators, address[] memory governors, uint96[] memory voteWeights) = getValidInputs( - DEFAULT_R1, - DEFAULT_R2, - DEFAULT_R3, - DEFAULT_NUM_BRIDGE_OPERATORS - ); - _defaultBridgeManagerInputs = abi.encode(bridgeOperators, governors, voteWeights); - _bridgeManagerContract = address(new MockBridgeManager(bridgeOperators, governors, voteWeights)); - - _gatewayLogic = address(new RoninGatewayV3()); - _gatewayContract = address(new TransparentUpgradeableProxyV2(_gatewayLogic, _admin, "")); - - _bridgeTrackingLogic = address(new BridgeTracking()); - _bridgeTrackingContract = address( - new TransparentUpgradeableProxyV2(_bridgeTrackingLogic, _bridgeManagerContract, "") - ); - - _bridgeSlashLogic = address(new MockBridgeSlash()); - _bridgeSlashContract = address( - new TransparentUpgradeableProxyV2( - _bridgeSlashLogic, - _bridgeManagerContract, - abi.encodeCall( - BridgeSlash.initialize, - (_validatorContract, _bridgeManagerContract, _bridgeTrackingContract, address(0)) - ) - ) - ); - } - - function _label() internal virtual { - vm.label(_admin, "ADMIN"); - vm.label(_validatorContract, "VALIDATOR"); - vm.label(_bridgeManagerContract, "BRIDGE_MANAGER"); - vm.label(_gatewayLogic, "GATEWAY_LOGIC"); - vm.label(_gatewayContract, "GATEWAY"); - vm.label(_bridgeTrackingLogic, "BRIDGE_TRACKING_LOGIC"); - vm.label(_bridgeTrackingContract, "BRIDGE_TRACKING"); - vm.label(_bridgeSlashLogic, "BRIDGE_SLASH_LOGIC"); - vm.label(_bridgeSlashContract, "BRIDGE_SLASH"); - } -}