diff --git a/abi/bscgovernor.abi b/abi/bscgovernor.abi index 4e32a2c7..93313dbe 100644 --- a/abi/bscgovernor.abi +++ b/abi/bscgovernor.abi @@ -566,19 +566,6 @@ ], "stateMutability": "view" }, - { - "type": "function", - "name": "governorProtector", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, { "type": "function", "name": "hasVoted", @@ -644,6 +631,19 @@ "outputs": [], "stateMutability": "nonpayable" }, + { + "type": "function", + "name": "isPaused", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, { "type": "function", "name": "lateQuorumVoteExtension", @@ -808,19 +808,6 @@ "outputs": [], "stateMutability": "nonpayable" }, - { - "type": "function", - "name": "paused", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "bool", - "internalType": "bool" - } - ], - "stateMutability": "view" - }, { "type": "function", "name": "proposalDeadline", @@ -1842,12 +1829,12 @@ }, { "type": "error", - "name": "Empty", + "name": "AlreadyPaused", "inputs": [] }, { "type": "error", - "name": "GovernorPaused", + "name": "Empty", "inputs": [] }, { @@ -1871,6 +1858,11 @@ } ] }, + { + "type": "error", + "name": "NotPaused", + "inputs": [] + }, { "type": "error", "name": "NotWhitelisted", @@ -1888,7 +1880,7 @@ }, { "type": "error", - "name": "OnlyGovernorProtector", + "name": "OnlyProtector", "inputs": [] }, { diff --git a/abi/stakehub.abi b/abi/stakehub.abi index e86e60b8..f02ab2cf 100644 --- a/abi/stakehub.abi +++ b/abi/stakehub.abi @@ -94,19 +94,6 @@ "outputs": [], "stateMutability": "nonpayable" }, - { - "type": "function", - "name": "assetProtector", - "inputs": [], - "outputs": [ - { - "name": "", - "type": "address", - "internalType": "address" - } - ], - "stateMutability": "view" - }, { "type": "function", "name": "blackList", @@ -1568,6 +1555,11 @@ ], "anonymous": false }, + { + "type": "error", + "name": "AlreadyPaused", + "inputs": [] + }, { "type": "error", "name": "AlreadySlashed", @@ -1661,7 +1653,7 @@ }, { "type": "error", - "name": "OnlyAssetProtector", + "name": "NotPaused", "inputs": [] }, { @@ -1669,6 +1661,11 @@ "name": "OnlyCoinbase", "inputs": [] }, + { + "type": "error", + "name": "OnlyProtector", + "inputs": [] + }, { "type": "error", "name": "OnlySelfDelegation", @@ -1700,11 +1697,6 @@ "name": "SelfDelegationNotEnough", "inputs": [] }, - { - "type": "error", - "name": "StakeHubPaused", - "inputs": [] - }, { "type": "error", "name": "TransferFailed", diff --git a/contracts/BC_fusion/BSCGovernor.sol b/contracts/BC_fusion/BSCGovernor.sol index f10edbbb..1ed0ec98 100644 --- a/contracts/BC_fusion/BSCGovernor.sol +++ b/contracts/BC_fusion/BSCGovernor.sol @@ -10,12 +10,14 @@ import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQ import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorPreventLateQuorumUpgradeable.sol"; import "./System.sol"; +import "./extension/Protectable.sol"; import "./lib/Utils.sol"; import "./interface/IGovToken.sol"; contract BSCGovernor is System, Initializable, + Protectable, GovernorUpgradeable, GovernorSettingsUpgradeable, GovernorCompatibilityBravoUpgradeable, @@ -48,50 +50,18 @@ contract BSCGovernor is error NotWhitelisted(); // @notice signature: 0x11b6707f error TotalSupplyNotEnough(); - // @notice signature: 0xe96776bf - error GovernorPaused(); - // @notice signature: 0x286300de - error OnlyGovernorProtector(); - // @notice signature: 0xb1d02c3d - error InBlackList(); // @notice signature: 0x867f3ee5 error OneLiveProposalPerProposer(); - /*----------------- events -----------------*/ - event Paused(); - event Resumed(); - event BlackListed(address indexed target); - event UnBlackListed(address indexed target); - /*----------------- storage -----------------*/ // target contract => is whitelisted for governance mapping(address => bool) public whitelistTargets; bool public proposeStarted; - bool public paused; - - address public governorProtector; - mapping(address => bool) public blackList; // @notice The latest proposal for each proposer mapping(address => uint256) public latestProposalIds; - /*----------------- modifier -----------------*/ - modifier whenNotPaused() { - if (paused) revert GovernorPaused(); - _; - } - - modifier onlyGovernorProtector() { - if (msg.sender != governorProtector) revert OnlyGovernorProtector(); - _; - } - - modifier notInBlackList() { - if (blackList[msg.sender]) revert InBlackList(); - _; - } - /*----------------- init -----------------*/ function initialize() external initializer onlyCoinbase onlyZeroGasPrice { __Governor_init("BSCGovernor"); @@ -107,40 +77,7 @@ contract BSCGovernor is // TODO // Different address will be set depending on the environment - governorProtector = address(0xdEaD); - } - - /*----------------- onlyGovernorProtector -----------------*/ - /** - * @dev Pause the whole system in emergency - */ - function pause() external onlyGovernorProtector { - paused = true; - emit Paused(); - } - - /** - * @dev Resume the whole system - */ - function resume() external onlyGovernorProtector { - paused = false; - emit Resumed(); - } - - /** - * @dev Add an address to the black list - */ - function addToBlackList(address account) external onlyGovernorProtector { - blackList[account] = true; - emit BlackListed(account); - } - - /** - * @dev Remove an address from the black list - */ - function removeFromBlackList(address account) external onlyGovernorProtector { - blackList[account] = false; - emit UnBlackListed(account); + __Protectable_init_unchained(address(0xdEaD)); } /*----------------- external functions -----------------*/ @@ -258,6 +195,11 @@ contract BSCGovernor is uint64 newMinPeriodAfterQuorum = value.bytesToUint64(8); if (newMinPeriodAfterQuorum == 0 || newMinPeriodAfterQuorum > 2 days) revert InvalidValue(key, value); _setLateQuorumVoteExtension(newMinPeriodAfterQuorum); + } else if (key.compareStrings("governorProtector")) { + if (value.length != 20) revert InvalidValue(key, value); + address newGovernorProtector = value.bytesToAddress(20); + if (newGovernorProtector == address(0)) revert InvalidValue(key, value); + _setProtector(newGovernorProtector); } else { revert UnknownParam(key, value); } diff --git a/contracts/BC_fusion/StakeHub.sol b/contracts/BC_fusion/StakeHub.sol index aa9b2832..0354c5e8 100644 --- a/contracts/BC_fusion/StakeHub.sol +++ b/contracts/BC_fusion/StakeHub.sol @@ -2,19 +2,20 @@ pragma solidity 0.8.17; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "./System.sol"; -import "./lib/Utils.sol"; +import "./extension/Protectable.sol"; import "./interface/IBSCValidatorSet.sol"; import "./interface/ICrossChain.sol"; import "./interface/IGovToken.sol"; import "./interface/IStakeCredit.sol"; import "./interface/ITokenHub.sol"; import "./lib/RLPDecode.sol"; +import "./lib/Utils.sol"; -contract StakeHub is System, Initializable { +contract StakeHub is System, Initializable, Protectable { using RLPDecode for *; using Utils for string; using Utils for bytes; @@ -38,12 +39,6 @@ contract StakeHub is System, Initializable { hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"; /*----------------- errors -----------------*/ - // @notice signature: 0xd7485e8f - error StakeHubPaused(); - // @notice signature: 0xb1d02c3d - error InBlackList(); - // @notice signature: 0xf2771a99 - error OnlyAssetProtector(); // @notice signature: 0x5f28f62b error ValidatorExisted(); // @notice signature: 0xfdf4600b @@ -94,7 +89,6 @@ contract StakeHub is System, Initializable { error InvalidSynPackage(); /*----------------- storage -----------------*/ - bool private _paused; uint8 private _isReceivingFund; uint256 public transferGasLimit; @@ -139,9 +133,6 @@ contract StakeHub is System, Initializable { // slash key => slash jail time mapping(bytes32 => uint256) private _felonyRecords; - address public assetProtector; - mapping(address => bool) public blackList; - /*----------------- structs and events -----------------*/ struct StakeMigrationPackage { address operatorAddress; // the operator address of the target validator to delegate to @@ -220,15 +211,11 @@ contract StakeHub is System, Initializable { event ValidatorEmptyJailed(address indexed operatorAddress); event ValidatorUnjailed(address indexed operatorAddress); event Claimed(address indexed operatorAddress, address indexed delegator, uint256 bnbAmount); - event Paused(); - event Resumed(); event MigrateSuccess(address indexed operatorAddress, address indexed delegator, uint256 shares, uint256 bnbAmount); event MigrateFailed( address indexed operatorAddress, address indexed delegator, uint256 bnbAmount, StakeMigrationRespCode respCode ); event unexpectedPackage(uint8 channelId, bytes msgBytes); - event BlackListed(address indexed target); - event UnBlackListed(address indexed target); /*----------------- modifiers -----------------*/ modifier validatorExist(address operatorAddress) { @@ -236,21 +223,6 @@ contract StakeHub is System, Initializable { _; } - modifier whenNotPaused() { - if (_paused) revert StakeHubPaused(); - _; - } - - modifier onlyAssetProtector() { - if (msg.sender != assetProtector) revert OnlyAssetProtector(); - _; - } - - modifier notInBlackList() { - if (blackList[msg.sender]) revert InBlackList(); - _; - } - receive() external payable { // to prevent BNB from being lost if (_isReceivingFund != 1) revert(); @@ -285,7 +257,7 @@ contract StakeHub is System, Initializable { // TODO // Different address will be set depending on the environment - assetProtector = DEAD_ADDRESS; + __Protectable_init_unchained(DEAD_ADDRESS); } /*----------------- Implement cross chain app -----------------*/ @@ -751,38 +723,6 @@ contract StakeHub is System, Initializable { IGovToken(GOV_TOKEN_ADDR).sync(valInfo.creditContract, operatorAddress); } - /** - * @dev Pause the whole system in emergency - */ - function pause() external onlyAssetProtector { - _paused = true; - emit Paused(); - } - - /** - * @dev Resume the whole system - */ - function resume() external onlyAssetProtector { - _paused = false; - emit Resumed(); - } - - /** - * @dev Add an address to the black list - */ - function addToBlackList(address account) external onlyAssetProtector { - blackList[account] = true; - emit BlackListed(account); - } - - /** - * @dev Remove an address from the black list - */ - function removeFromBlackList(address account) external onlyAssetProtector { - blackList[account] = false; - emit UnBlackListed(account); - } - /** * @param key the key of the param * @param value the value of the param @@ -853,11 +793,11 @@ contract StakeHub is System, Initializable { uint256 newJailedPerDay = value.bytesToUint256(32); if (newJailedPerDay == 0) revert InvalidValue(key, value); maxFelonyBetweenBreatheBlock = newJailedPerDay; - } else if (key.compareStrings("assetProtector")) { + } else if (key.compareStrings("stakeHubProtector")) { if (value.length != 20) revert InvalidValue(key, value); - address newAssetProtector = value.bytesToAddress(20); - if (newAssetProtector == address(0)) revert InvalidValue(key, value); - assetProtector = newAssetProtector; + address newStakeHubProtector = value.bytesToAddress(20); + if (newStakeHubProtector == address(0)) revert InvalidValue(key, value); + _setProtector(newStakeHubProtector); } else { revert UnknownParam(key, value); } @@ -865,13 +805,6 @@ contract StakeHub is System, Initializable { } /*----------------- view functions -----------------*/ - /** - * @return whether the system is paused - */ - function isPaused() external view returns (bool) { - return _paused; - } - /** * @param operatorAddress the operator address of the validator * @param index the index of the day to query(timestamp / 1 days) diff --git a/contracts/BC_fusion/TokenRecoverPortal.sol b/contracts/BC_fusion/TokenRecoverPortal.sol index 2f560d1c..3869e434 100644 --- a/contracts/BC_fusion/TokenRecoverPortal.sol +++ b/contracts/BC_fusion/TokenRecoverPortal.sol @@ -5,9 +5,10 @@ import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable. import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import "./System.sol"; +import "./extension/Protectable.sol"; import "./interface/ITokenHub.sol"; import "./interface/ITokenRecoverPortal.sol"; -import "./System.sol"; import "./lib/Utils.sol"; /** @@ -17,7 +18,7 @@ import "./lib/Utils.sol"; * The BC users can recover the token from TokenHub after the merkle tree root is generated. * For more details, please refer to the BEP-299(https://github.com/bnb-chain/BEPs/pull/299). */ -contract TokenRecoverPortal is System, ReentrancyGuardUpgradeable { +contract TokenRecoverPortal is System, Initializable, ReentrancyGuardUpgradeable, Protectable { using Utils for string; using Utils for bytes; @@ -32,21 +33,6 @@ contract TokenRecoverPortal is System, ReentrancyGuardUpgradeable { // recoveredMap is used to record the recovered token. mapping(bytes32 => bool) private recoveredMap; - // assetProtector is the address that is allowed to pause the #recover. - address public assetProtector; - // paused is used to pause the #recover. - bool private _paused; - - modifier whenNotPaused() { - if (_paused) revert TokenRecoverPortalPaused(); - _; - } - - modifier onlyAssetProtector() { - if (msg.sender != assetProtector) revert OnlyAssetProtector(); - _; - } - modifier merkelRootReady() { if (!merkleRootAlreadyInit) revert MerkleRootNotInitialize(); if (merkleRoot == bytes32(0)) revert MerkleRootNotInitialize(); @@ -75,34 +61,20 @@ contract TokenRecoverPortal is System, ReentrancyGuardUpgradeable { error MerkleRootNotInitialize(); // @notice signature: 0xc629ac81 error TokenRecoverPortalPaused(); - // @notice signature: 0xb1d02c3d - error InBlackList(); - // @notice signature: 0xf2771a99 - error OnlyAssetProtector(); // @notice signature: 0x459e3e99 error ApprovalAddressNotInitialize(); /*----------------- events -----------------*/ - // This event is triggered whenever a call to #pause succeeds. - event Paused(); - // This event is triggered whenever a call to #resumed succeeds. - event Resumed(); // This event is triggered whenever a call to #recover succeeds. event TokenRecoverRequested(bytes32 tokenSymbol, address account, uint256 amount); /*----------------- init -----------------*/ function initialize() external initializer onlyCoinbase onlyZeroGasPrice { __ReentrancyGuard_init_unchained(); - } - - function pause() external onlyAssetProtector { - _paused = true; - emit Paused(); - } - function resume() external onlyAssetProtector { - _paused = false; - emit Resumed(); + // TODO + // Different address will be set depending on the environment + __Protectable_init_unchained(address(0xdEaD)); } /** @@ -275,11 +247,11 @@ contract TokenRecoverPortal is System, ReentrancyGuardUpgradeable { if (newMerkleRoot == bytes32(0)) revert InvalidValue(key, value); merkleRoot = newMerkleRoot; merkleRootAlreadyInit = true; - } else if (key.compareStrings("assetProtector")) { + } else if (key.compareStrings("tokenRecoverPortalProtector")) { if (value.length != 20) revert InvalidValue(key, value); - address newAssetProtector = value.bytesToAddress(20); - if (newAssetProtector == address(0)) revert InvalidValue(key, value); - assetProtector = newAssetProtector; + address newTokenRecoverPortalProtector = value.bytesToAddress(20); + if (newTokenRecoverPortalProtector == address(0)) revert InvalidValue(key, value); + _setProtector(newTokenRecoverPortalProtector); } else { revert UnknownParam(key, value); } @@ -292,7 +264,7 @@ contract TokenRecoverPortal is System, ReentrancyGuardUpgradeable { * @param tokenSymbol is the symbol of token. * @param attacker is the address of the attacker. */ - function cancelTokenRecover(bytes32 tokenSymbol, address attacker) external onlyAssetProtector { + function cancelTokenRecover(bytes32 tokenSymbol, address attacker) external onlyProtector { ITokenHub(TOKEN_HUB_ADDR).cancelTokenRecoverLock(tokenSymbol, attacker); } } diff --git a/contracts/BC_fusion/extension/Protectable.sol b/contracts/BC_fusion/extension/Protectable.sol new file mode 100644 index 00000000..bd949369 --- /dev/null +++ b/contracts/BC_fusion/extension/Protectable.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.17; + +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; + +abstract contract Protectable is Initializable { + /*----------------- storage -----------------*/ + bool private _paused; + address private _protector; + mapping(address => bool) public blackList; + + /*----------------- errors -----------------*/ + // @notice signature: 0x1785c681 + error AlreadyPaused(); + error NotPaused(); + // @notice signature: 0xb1d02c3d + error InBlackList(); + // @notice signature: 0x06fbb1e3 + error OnlyProtector(); + + /*----------------- events -----------------*/ + event Paused(); + event Resumed(); + event BlackListed(address indexed target); + event UnBlackListed(address indexed target); + + /*----------------- modifier -----------------*/ + modifier whenNotPaused() { + if (_paused) revert AlreadyPaused(); + _; + } + + modifier whenPaused() { + if (!_paused) revert NotPaused(); + _; + } + + modifier onlyProtector() { + if (msg.sender != _protector) revert OnlyProtector(); + _; + } + + modifier notInBlackList() { + if (blackList[msg.sender]) revert InBlackList(); + _; + } + + /*----------------- initializer -----------------*/ + function __Protectable_init(address protector) internal onlyInitializing { + __Protectable_init_unchained(protector); + } + + function __Protectable_init_unchained(address protector) internal onlyInitializing { + _protector = protector; + } + + /*----------------- external functions -----------------*/ + /** + * @return whether the system is paused + */ + function isPaused() external view returns (bool) { + return _paused; + } + + /** + * @dev Pause the whole system in emergency + */ + function pause() external virtual onlyProtector whenNotPaused { + _paused = true; + emit Paused(); + } + + /** + * @dev Resume the whole system + */ + function resume() external virtual onlyProtector whenPaused { + _paused = false; + emit Resumed(); + } + + /** + * @dev Add an address to the black list + */ + function addToBlackList(address account) external virtual onlyProtector { + blackList[account] = true; + emit BlackListed(account); + } + + /** + * @dev Remove an address from the black list + */ + function removeFromBlackList(address account) external virtual onlyProtector { + delete blackList[account]; + emit UnBlackListed(account); + } + + /*----------------- internal functions -----------------*/ + function _setProtector(address protector) internal { + _protector = protector; + } + + uint256[50] private __reservedSlot; +} diff --git a/scripts/generate.py b/scripts/generate.py index f92bac11..b03dc83e 100644 --- a/scripts/generate.py +++ b/scripts/generate.py @@ -132,7 +132,7 @@ def generate_slash_indicator(misdemeanor_threshold, felony_threshold, init_felon def generate_stake_hub( breathe_block_interval, init_bc_consensus_addresses, init_bc_vote_addresses, unbond_period, downtime_jail_time, - felony_jail_time, asset_protector + felony_jail_time, stake_hub_protector ): contract = "BC_fusion/StakeHub.sol" backup_file( @@ -146,7 +146,7 @@ def generate_stake_hub( replace(contract, r"unbondPeriod = .*;", f"unbondPeriod = {unbond_period};") replace(contract, r"downtimeJailTime = .*;", f"downtimeJailTime = {downtime_jail_time};") replace(contract, r"felonyJailTime = .*;", f"felonyJailTime = {felony_jail_time};") - replace(contract, r"assetProtector = .*;", f"assetProtector = {asset_protector};") + replace(contract, r"__Protectable_init_unchained\(.*\);", f"__Protectable_init_unchained({stake_hub_protector});") def generate_governor( @@ -163,7 +163,7 @@ def generate_governor( replace_parameter( contract, "uint64 private constant INIT_MIN_PERIOD_AFTER_QUORUM", f"{init_min_period_after_quorum}" ) - replace(contract, r"governorProtector = .*;", f"governorProtector = {governor_protector};") + replace(contract, r"__Protectable_init_unchained\(.*\);", f"__Protectable_init_unchained({governor_protector});") def generate_timelock(init_minimal_delay): @@ -229,13 +229,17 @@ def generate_token_hub( ) -def generate_token_recover_portal(source_chain_id): +def generate_token_recover_portal(source_chain_id, token_recover_portal_protector): contract = "BC_fusion/TokenRecoverPortal.sol" backup_file( os.path.join(work_dir, "contracts", contract), os.path.join(work_dir, "contracts", contract[:-4] + ".bak") ) replace_parameter(contract, "string public constant SOURCE_CHAIN_ID", f"\"{source_chain_id}\"") + replace( + contract, r"__Protectable_init_unchained\(.*\);", + f"__Protectable_init_unchained({token_recover_portal_protector});" + ) def generate_validator_set(init_validatorset_bytes, init_burn_ratio, epoch): @@ -304,8 +308,9 @@ def mainnet(): # TODO: update the following parameters init_bc_consensus_addresses = 'hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"' init_bc_vote_addresses = 'hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"' - asset_protector = "address(0xdEaD)" + stake_hub_protector = "address(0xdEaD)" governor_protector = "address(0xdEaD)" + token_recover_portal_protector = "address(0xdEaD)" epoch = "200" misdemeanor_threshold = "50" @@ -334,10 +339,10 @@ def mainnet(): generate_relayer_hub(whitelist_1, whitelist_2) generate_tendermint_light_client(init_consensus_bytes) generate_validator_set(init_validatorset_bytes, init_burn_ratio, epoch) - generate_token_recover_portal(source_chain_id) + generate_token_recover_portal(source_chain_id, token_recover_portal_protector) generate_stake_hub( breathe_block_interval, init_bc_consensus_addresses, init_bc_vote_addresses, unbond_period, downtime_jail_time, - felony_jail_time, asset_protector + felony_jail_time, stake_hub_protector ) generate_governor( block_interval, init_voting_delay, init_voting_period, init_min_period_after_quorum, governor_protector @@ -370,8 +375,9 @@ def testnet(): # TODO: update the following parameters init_bc_consensus_addresses = 'hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"' init_bc_vote_addresses = 'hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"' - asset_protector = "address(0xdEaD)" + stake_hub_protector = "address(0xdEaD)" governor_protector = "address(0xdEaD)" + token_recover_portal_protector = "address(0xdEaD)" epoch = "200" misdemeanor_threshold = "50" @@ -400,10 +406,10 @@ def testnet(): generate_relayer_hub(whitelist_1, whitelist_2) generate_tendermint_light_client(init_consensus_bytes) generate_validator_set(init_validatorset_bytes, init_burn_ratio, epoch) - generate_token_recover_portal(source_chain_id) + generate_token_recover_portal(source_chain_id, token_recover_portal_protector) generate_stake_hub( breathe_block_interval, init_bc_consensus_addresses, init_bc_vote_addresses, unbond_period, downtime_jail_time, - felony_jail_time, asset_protector + felony_jail_time, stake_hub_protector ) generate_governor( block_interval, init_voting_delay, init_voting_period, init_min_period_after_quorum, governor_protector @@ -440,7 +446,7 @@ def dev( str = 'hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"', init_bc_vote_addresses: str = 'hex"00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000"', - asset_protector: Annotated[str, typer.Option(help="assetProtector of StakeHub")] = "address(0xdEaD)", + stake_hub_protector: Annotated[str, typer.Option(help="assetProtector of StakeHub")] = "address(0xdEaD)", unbond_period: Annotated[str, typer.Option(help="unbondPeriod of StakeHub")] = "7 days", downtime_jail_time: Annotated[str, typer.Option(help="downtimeJailTime of StakeHub")] = "2 days", felony_jail_time: Annotated[str, typer.Option(help="felonyJailTime of StakeHub")] = "30 days", @@ -457,7 +463,9 @@ def dev( reward_upper_limit: Annotated[str, typer.Option(help="REWARD_UPPER_LIMIT of TokenHub")] = "1e18", init_minimum_relay_fee: Annotated[str, typer.Option(help="INIT_MINIMUM_RELAY_FEE of TokenHub")] = "2e15", lock_period_for_token_recover: Annotated[str, - typer.Option(help="LOCK_PERIOD_FOR_TOKEN_RECOVER of TokenHub")] = "7 days" + typer.Option(help="LOCK_PERIOD_FOR_TOKEN_RECOVER of TokenHub")] = "7 days", + token_recover_portal_protector: Annotated[str, + typer.Option(help="protector of TokenRecoverPortal")] = "address(0xdEaD)" ): global network, chain_id, hex_chain_id network = "dev" @@ -487,10 +495,10 @@ def dev( generate_relayer_hub(whitelist_1, whitelist_2) generate_tendermint_light_client(init_consensus_bytes) generate_validator_set(init_validatorset_bytes, init_burn_ratio, epoch) - generate_token_recover_portal(source_chain_id) + generate_token_recover_portal(source_chain_id, token_recover_portal_protector) generate_stake_hub( breathe_block_interval, init_bc_consensus_addresses, init_bc_vote_addresses, unbond_period, downtime_jail_time, - felony_jail_time, asset_protector + felony_jail_time, stake_hub_protector ) generate_governor( block_interval, init_voting_delay, init_voting_period, init_min_period_after_quorum, governor_protector diff --git a/test/utils/interface/IBSCGovernor.sol b/test/utils/interface/IBSCGovernor.sol index fa5a9d70..0efc7948 100644 --- a/test/utils/interface/IBSCGovernor.sol +++ b/test/utils/interface/IBSCGovernor.sol @@ -10,17 +10,21 @@ interface BSCGovernor { uint96 votes; } + error AlreadyPaused(); error Empty(); - error GovernorPaused(); + error InBlackList(); error InvalidValue(string key, bytes value); + error NotPaused(); error NotWhitelisted(); + error OneLiveProposalPerProposer(); error OnlyCoinbase(); - error OnlyGovernorProtector(); + error OnlyProtector(); error OnlySystemContract(address systemContract); error OnlyZeroGasPrice(); error TotalSupplyNotEnough(); error UnknownParam(string key, bytes value); + event BlackListed(address indexed target); event EIP712DomainChanged(); event Initialized(uint8 version); event LateQuorumVoteExtensionSet(uint64 oldVoteExtension, uint64 newVoteExtension); @@ -45,6 +49,7 @@ interface BSCGovernor { event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); event Resumed(); event TimelockChange(address oldTimelock, address newTimelock); + event UnBlackListed(address indexed target); event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); event VoteCastWithParams( address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params @@ -60,6 +65,8 @@ interface BSCGovernor { function COUNTING_MODE() external pure returns (string memory); function EXTENDED_BALLOT_TYPEHASH() external view returns (bytes32); function STAKING_CHANNELID() external view returns (uint8); + function addToBlackList(address account) external; + function blackList(address) external view returns (bool); function cancel(uint256 proposalId) external; function cancel( address[] memory targets, @@ -127,7 +134,6 @@ interface BSCGovernor { uint256 timepoint, bytes memory params ) external view returns (uint256); - function governorProtector() external view returns (address); function hasVoted(uint256 proposalId, address account) external view returns (bool); function hashProposal( address[] memory targets, @@ -136,7 +142,9 @@ interface BSCGovernor { bytes32 descriptionHash ) external pure returns (uint256); function initialize() external; + function isPaused() external view returns (bool); function lateQuorumVoteExtension() external view returns (uint64); + function latestProposalIds(address) external view returns (uint256); function name() external view returns (string memory); function onERC1155BatchReceived( address, @@ -148,7 +156,6 @@ interface BSCGovernor { function onERC1155Received(address, address, uint256, uint256, bytes memory) external returns (bytes4); function onERC721Received(address, address, uint256, bytes memory) external returns (bytes4); function pause() external; - function paused() external view returns (bool); function proposalDeadline(uint256 proposalId) external view returns (uint256); function proposalEta(uint256 proposalId) external view returns (uint256); function proposalProposer(uint256 proposalId) external view returns (address); @@ -196,6 +203,7 @@ interface BSCGovernor { function quorumNumerator() external view returns (uint256); function quorumVotes() external view returns (uint256); function relay(address target, uint256 value, bytes memory data) external payable; + function removeFromBlackList(address account) external; function resume() external; function setLateQuorumVoteExtension(uint64 newVoteExtension) external; function setProposalThreshold(uint256 newProposalThreshold) external; diff --git a/test/utils/interface/IStakeHub.sol b/test/utils/interface/IStakeHub.sol index 11cb83c2..a36e636f 100644 --- a/test/utils/interface/IStakeHub.sol +++ b/test/utils/interface/IStakeHub.sol @@ -18,6 +18,7 @@ interface StakeHub { string details; } + error AlreadyPaused(); error AlreadySlashed(); error ConsensusAddressExpired(); error DelegationAmountTooSmall(); @@ -34,14 +35,14 @@ interface StakeHub { error InvalidVoteAddress(); error JailTimeNotExpired(); error NoMoreFelonyAllowed(); - error OnlyAssetProtector(); + error NotPaused(); error OnlyCoinbase(); + error OnlyProtector(); error OnlySelfDelegation(); error OnlySystemContract(address systemContract); error OnlyZeroGasPrice(); error SameValidator(); error SelfDelegationNotEnough(); - error StakeHubPaused(); error TransferFailed(); error UnknownParam(string key, bytes value); error UpdateTooFrequently(); @@ -51,6 +52,7 @@ interface StakeHub { error VoteAddressExpired(); error ZeroShares(); + event BlackListed(address indexed target); event Claimed(address indexed operatorAddress, address indexed delegator, uint256 bnbAmount); event CommissionRateEdited(address indexed operatorAddress, uint64 newCommissionRate); event ConsensusAddressEdited(address indexed operatorAddress, address indexed newConsensusAddress); @@ -75,6 +77,7 @@ interface StakeHub { event RewardDistributeFailed(address indexed operatorAddress, bytes failReason); event RewardDistributed(address indexed operatorAddress, uint256 reward); event StakeCreditInitialized(address indexed operatorAddress, address indexed creditContract); + event UnBlackListed(address indexed target); event Undelegated(address indexed operatorAddress, address indexed delegator, uint256 shares, uint256 bnbAmount); event ValidatorCreated( address indexed consensusAddress, @@ -100,7 +103,6 @@ interface StakeHub { function REDELEGATE_FEE_RATE_BASE() external view returns (uint256); function STAKING_CHANNELID() external view returns (uint8); function addToBlackList(address account) external; - function assetProtector() external view returns (address); function blackList(address) external view returns (bool); function claim(address operatorAddress, uint256 requestNumber) external; function claimBatch(address[] memory operatorAddresses, uint256[] memory requestNumbers) external;