diff --git a/script/7_DeployBootstrap.s.sol b/script/7_DeployBootstrap.s.sol index cf3543d9..97e28751 100644 --- a/script/7_DeployBootstrap.s.sol +++ b/script/7_DeployBootstrap.s.sol @@ -66,7 +66,6 @@ contract DeployBootstrapOnly is BaseScript { exocoreValidatorSet.addr, block.timestamp + 365 days + 24 hours, 24 hours, - payable(exocoreValidatorSet.addr), whitelistTokens, // vault is auto deployed address(proxyAdmin) ) diff --git a/script/integration/1_DeployBootstrap.s.sol b/script/integration/1_DeployBootstrap.s.sol index 838471a0..6fddf0ac 100644 --- a/script/integration/1_DeployBootstrap.s.sol +++ b/script/integration/1_DeployBootstrap.s.sol @@ -129,7 +129,6 @@ contract DeployContracts is Script { vm.addr(contractDeployer), block.timestamp + 3 minutes, 1 seconds, - payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin) ) diff --git a/src/core/BaseRestakingController.sol b/src/core/BaseRestakingController.sol index b1a1bcd3..ef8a82a9 100644 --- a/src/core/BaseRestakingController.sol +++ b/src/core/BaseRestakingController.sol @@ -86,9 +86,8 @@ abstract contract BaseRestakingController is ).addExecutorOrderedExecutionOption(); MessagingFee memory fee = _quote(EXOCORE_CHAIN_ID, payload, options, false); - MessagingReceipt memory receipt = _lzSend( - EXOCORE_CHAIN_ID, payload, options, MessagingFee(fee.nativeFee, 0), exocoreValidatorSetAddress, false - ); + MessagingReceipt memory receipt = + _lzSend(EXOCORE_CHAIN_ID, payload, options, MessagingFee(fee.nativeFee, 0), msg.sender, false); emit MessageSent(action, receipt.guid, receipt.nonce, receipt.fee.nativeFee); } diff --git a/src/core/Bootstrap.sol b/src/core/Bootstrap.sol index 6a31ca3f..6db9af07 100644 --- a/src/core/Bootstrap.sol +++ b/src/core/Bootstrap.sol @@ -48,7 +48,6 @@ contract Bootstrap is address owner, uint256 spawnTime_, uint256 offsetDuration_, - address payable exocoreValidatorSetAddress_, address[] calldata whitelistTokens_, address customProxyAdmin_ ) external initializer { @@ -58,14 +57,10 @@ contract Bootstrap is require(spawnTime_ > offsetDuration_, "Bootstrap: spawn time should be greater than offset duration"); uint256 lockTime = spawnTime_ - offsetDuration_; require(lockTime > block.timestamp, "Bootstrap: lock time should be in the future"); - require( - exocoreValidatorSetAddress_ != address(0), "Bootstrap: exocore validator set address should not be empty" - ); require(customProxyAdmin_ != address(0), "Bootstrap: custom proxy admin should not be empty"); exocoreSpawnTime = spawnTime_; offsetDuration = offsetDuration_; - exocoreValidatorSetAddress = exocoreValidatorSetAddress_; _addWhitelistTokens(whitelistTokens_); diff --git a/src/core/ClientChainGateway.sol b/src/core/ClientChainGateway.sol index 885cca39..cd081c27 100644 --- a/src/core/ClientChainGateway.sol +++ b/src/core/ClientChainGateway.sol @@ -58,15 +58,10 @@ contract ClientChainGateway is // initialization happens from another contract so it must be external. // reinitializer(2) is used so that the ownable and oappcore functions can be called again. - function initialize(address payable exocoreValidatorSetAddress_) external reinitializer(2) { + function initialize(address owner_) external reinitializer(2) { _clearBootstrapData(); - require( - exocoreValidatorSetAddress_ != address(0), - "ClientChainGateway: exocore validator set address should not be empty" - ); - - exocoreValidatorSetAddress = exocoreValidatorSetAddress_; + require(owner_ != address(0), "ClientChainGateway: contract owner should not be empty"); _registeredResponseHooks[Action.REQUEST_DEPOSIT] = this.afterReceiveDepositResponse.selector; _registeredResponseHooks[Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE] = @@ -83,8 +78,8 @@ contract ClientChainGateway is bootstrapped = true; - _transferOwnership(exocoreValidatorSetAddress); - __OAppCore_init_unchained(exocoreValidatorSetAddress); + _transferOwnership(owner_); + __OAppCore_init_unchained(owner_); __Pausable_init_unchained(); __ReentrancyGuard_init_unchained(); } @@ -105,19 +100,11 @@ contract ClientChainGateway is delete registeredOperators; } - function pause() external { - require( - msg.sender == exocoreValidatorSetAddress, - "ClientChainGateway: caller is not Exocore validator set aggregated address" - ); + function pause() external onlyOwner { _pause(); } - function unpause() external { - require( - msg.sender == exocoreValidatorSetAddress, - "ClientChainGateway: caller is not Exocore validator set aggregated address" - ); + function unpause() external onlyOwner { _unpause(); } diff --git a/src/core/ExocoreGateway.sol b/src/core/ExocoreGateway.sol index a0e56961..27d02b9b 100644 --- a/src/core/ExocoreGateway.sol +++ b/src/core/ExocoreGateway.sol @@ -50,17 +50,12 @@ contract ExocoreGateway is receive() external payable {} - function initialize(address payable exocoreValidatorSetAddress_) external initializer { - require( - exocoreValidatorSetAddress_ != address(0), - "ExocoreGateway: validator set address cannot be the zero address" - ); - - exocoreValidatorSetAddress = exocoreValidatorSetAddress_; + function initialize(address owner_) external initializer { + require(owner_ != address(0), "ExocoreGateway: owner address cannot be the zero address"); _initializeWhitelistFunctionSelectors(); - _transferOwnership(exocoreValidatorSetAddress); - __OAppCore_init_unchained(exocoreValidatorSetAddress); + _transferOwnership(owner_); + __OAppCore_init_unchained(owner_); __Pausable_init_unchained(); __ReentrancyGuard_init_unchained(); } @@ -76,19 +71,11 @@ contract ExocoreGateway is this.requestDepositThenDelegateTo.selector; } - function pause() external { - require( - msg.sender == exocoreValidatorSetAddress, - "ExocoreGateway: caller is not Exocore validator set aggregated address" - ); + function pause() external onlyOwner { _pause(); } - function unpause() external { - require( - msg.sender == exocoreValidatorSetAddress, - "ExocoreGateway: caller is not Exocore validator set aggregated address" - ); + function unpause() external onlyOwner { _unpause(); } @@ -444,7 +431,7 @@ contract ExocoreGateway is MessagingFee memory fee = _quote(srcChainId, payload, options, false); MessagingReceipt memory receipt = - _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), exocoreValidatorSetAddress, payByApp); + _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), msg.sender, payByApp); emit MessageSent(act, receipt.guid, receipt.nonce, receipt.fee.nativeFee); } diff --git a/src/storage/GatewayStorage.sol b/src/storage/GatewayStorage.sol index b1b5d621..07ce10a6 100644 --- a/src/storage/GatewayStorage.sol +++ b/src/storage/GatewayStorage.sol @@ -15,8 +15,6 @@ contract GatewayStorage { } mapping(Action => bytes4) internal _whiteListFunctionSelectors; - address payable public exocoreValidatorSetAddress; - mapping(uint32 eid => mapping(bytes32 sender => uint64 nonce)) public inboundNonce; event MessageSent(Action indexed act, bytes32 packetId, uint64 nonce, uint256 nativeFee); diff --git a/test/foundry/unit/Bootstrap.t.sol b/test/foundry/unit/Bootstrap.t.sol index 2197256c..49d7934f 100644 --- a/test/foundry/unit/Bootstrap.t.sol +++ b/test/foundry/unit/Bootstrap.t.sol @@ -107,14 +107,7 @@ contract BootstrapTest is Test { address(proxyAdmin), abi.encodeCall( bootstrap.initialize, - ( - deployer, - spawnTime, - offsetDuration, - payable(exocoreValidatorSet), - whitelistTokens, - address(proxyAdmin) - ) + (deployer, spawnTime, offsetDuration, whitelistTokens, address(proxyAdmin)) ) ) ) @@ -958,14 +951,7 @@ contract BootstrapTest is Test { address(proxyAdmin), abi.encodeCall( bootstrap.initialize, - ( - address(0x0), - spawnTime, - offsetDuration, - payable(exocoreValidatorSet), - whitelistTokens, - address(proxyAdmin) - ) + (address(0x0), spawnTime, offsetDuration, whitelistTokens, address(proxyAdmin)) ) ) ) @@ -988,14 +974,7 @@ contract BootstrapTest is Test { address(proxyAdmin), abi.encodeCall( bootstrap.initialize, - ( - deployer, - block.timestamp - 10, - offsetDuration, - payable(exocoreValidatorSet), - whitelistTokens, - address(proxyAdmin) - ) + (deployer, block.timestamp - 10, offsetDuration, whitelistTokens, address(proxyAdmin)) ) ) ) @@ -1016,8 +995,7 @@ contract BootstrapTest is Test { address(bootstrapLogic), address(proxyAdmin), abi.encodeCall( - bootstrap.initialize, - (deployer, spawnTime, 0, payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin)) + bootstrap.initialize, (deployer, spawnTime, 0, whitelistTokens, address(proxyAdmin)) ) ) ) @@ -1038,10 +1016,7 @@ contract BootstrapTest is Test { new TransparentUpgradeableProxy( address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall( - bootstrap.initialize, - (deployer, 21, 22, payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin)) - ) + abi.encodeCall(bootstrap.initialize, (deployer, 21, 22, whitelistTokens, address(proxyAdmin))) ) ) ) @@ -1061,39 +1036,7 @@ contract BootstrapTest is Test { new TransparentUpgradeableProxy( address(bootstrapLogic), address(proxyAdmin), - abi.encodeCall( - bootstrap.initialize, - (deployer, 21, 9, payable(exocoreValidatorSet), whitelistTokens, address(proxyAdmin)) - ) - ) - ) - ) - ); - } - - function test15_Initialize_ExocoreValSetZero() public { - vm.startPrank(deployer); - Bootstrap bootstrapLogic = new Bootstrap( - address(clientChainLzEndpoint), exocoreChainId, address(vaultBeacon), address(beaconProxyBytecode) - ); - vm.expectRevert("Bootstrap: exocore validator set address should not be empty"); - Bootstrap( - payable( - address( - new TransparentUpgradeableProxy( - address(bootstrapLogic), - address(proxyAdmin), - abi.encodeCall( - bootstrap.initialize, - ( - deployer, - spawnTime, - offsetDuration, - payable(address(0)), - whitelistTokens, - address(proxyAdmin) - ) - ) + abi.encodeCall(bootstrap.initialize, (deployer, 21, 9, whitelistTokens, address(proxyAdmin))) ) ) ) @@ -1113,15 +1056,7 @@ contract BootstrapTest is Test { address(bootstrapLogic), address(proxyAdmin), abi.encodeCall( - bootstrap.initialize, - ( - deployer, - spawnTime, - offsetDuration, - payable(exocoreValidatorSet), - whitelistTokens, - address(0x0) - ) + bootstrap.initialize, (deployer, spawnTime, offsetDuration, whitelistTokens, address(0x0)) ) ) ) diff --git a/test/foundry/unit/ClientChainGateway.t.sol b/test/foundry/unit/ClientChainGateway.t.sol index f56033e4..4db65ea8 100644 --- a/test/foundry/unit/ClientChainGateway.t.sol +++ b/test/foundry/unit/ClientChainGateway.t.sol @@ -202,7 +202,7 @@ contract Pausable is SetUp { } function test_RevertWhen_UnauthorizedPauser() public { - vm.expectRevert("ClientChainGateway: caller is not Exocore validator set aggregated address"); + vm.expectRevert("Ownable: caller is not the owner"); vm.startPrank(deployer.addr); clientGateway.pause(); } @@ -260,10 +260,6 @@ contract Initialize is SetUp { assertEq(address(clientGateway.EXO_CAPSULE_BEACON()), address(capsuleBeacon)); } - function test_ExocoreValidatoSetAddressInitialized() public { - assertEq(clientGateway.exocoreValidatorSetAddress(), exocoreValidatorSet.addr); - } - function test_OwnerInitialized() public { assertEq(clientGateway.owner(), exocoreValidatorSet.addr); } diff --git a/test/foundry/unit/ExocoreGateway.t.sol b/test/foundry/unit/ExocoreGateway.t.sol index efd64cb6..7e98bad8 100644 --- a/test/foundry/unit/ExocoreGateway.t.sol +++ b/test/foundry/unit/ExocoreGateway.t.sol @@ -137,7 +137,7 @@ contract Pausable is SetUp { } function test_RevertWhen_UnauthorizedPauser() public { - vm.expectRevert(bytes("ExocoreGateway: caller is not Exocore validator set aggregated address")); + vm.expectRevert(bytes("Ownable: caller is not the owner")); vm.startPrank(deployer.addr); exocoreGateway.pause(); } diff --git a/test/mocks/ExocoreGatewayMock.sol b/test/mocks/ExocoreGatewayMock.sol index 2b024ec9..0e79167f 100644 --- a/test/mocks/ExocoreGatewayMock.sol +++ b/test/mocks/ExocoreGatewayMock.sol @@ -76,14 +76,12 @@ contract ExocoreGatewayMock is receive() external payable {} - function initialize(address payable exocoreValidatorSetAddress_) external initializer { - require(exocoreValidatorSetAddress_ != address(0), "ExocoreGateway: invalid exocore validator set address"); - - exocoreValidatorSetAddress = exocoreValidatorSetAddress_; + function initialize(address owner_) external initializer { + require(owner_ != address(0), "ExocoreGateway: owner can not be zero address"); _initializeWhitelistFunctionSelectors(); - _transferOwnership(exocoreValidatorSetAddress); - __OAppCore_init_unchained(exocoreValidatorSetAddress); + _transferOwnership(owner_); + __OAppCore_init_unchained(owner_); __Pausable_init_unchained(); } @@ -96,19 +94,11 @@ contract ExocoreGatewayMock is _whiteListFunctionSelectors[Action.REQUEST_WITHDRAW_REWARD_FROM_EXOCORE] = this.requestWithdrawReward.selector; } - function pause() external { - require( - msg.sender == exocoreValidatorSetAddress, - "ExocoreGateway: caller is not Exocore validator set aggregated address" - ); + function pause() external onlyOwner { _pause(); } - function unpause() external { - require( - msg.sender == exocoreValidatorSetAddress, - "ExocoreGateway: caller is not Exocore validator set aggregated address" - ); + function unpause() external onlyOwner { _unpause(); } @@ -189,6 +179,9 @@ contract ExocoreGatewayMock is super.setPeer(clientChainId, clientChainGateway); } + // Though this function would call precompiled contract, all precompiled contracts belong to Exocore + // and we could make sure its implementation does not have dangerous behavior like reentrancy. + // slither-disable-next-line reentrancy-no-eth function addWhitelistTokens( uint32 clientChainId, bytes32[] calldata tokens, @@ -461,7 +454,7 @@ contract ExocoreGatewayMock is MessagingFee memory fee = _quote(srcChainId, payload, options, false); MessagingReceipt memory receipt = - _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), exocoreValidatorSetAddress, payByApp); + _lzSend(srcChainId, payload, options, MessagingFee(fee.nativeFee, 0), msg.sender, payByApp); emit MessageSent(act, receipt.guid, receipt.nonce, receipt.fee.nativeFee); }