diff --git a/lib/forge-std b/lib/forge-std index 3b1c123..52715a2 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 3b1c123f115b5d9bb371a18cc808c1abfb4369c3 +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 diff --git a/src/contracts/StakingContract.sol b/src/contracts/StakingContract.sol index 7363027..7f1d45d 100644 --- a/src/contracts/StakingContract.sol +++ b/src/contracts/StakingContract.sol @@ -740,6 +740,7 @@ contract StakingContract { } /// @notice Utility to ban a user, exits the validators provided if account is not OFAC sanctioned + /// @notice Blocks the account from depositing, the account is still alowed to exit & withdraw if not sanctioned /// @param _account Account to ban /// @param _publicKeys Public keys to exit function blockAccount(address _account, bytes calldata _publicKeys) external onlyAdmin { @@ -753,10 +754,16 @@ contract StakingContract { _requestExits(_publicKeys, _account); } + /// @notice Utility to unban a user + /// @param _account Account to unban function unblock(address _account) external onlyAdmin { StakingContractStorageLib.getBlocklist().value[_account] = false; } + /// @notice Utility to check if an account is blocked or sanctioned + /// @param _account Account to check + /// @return isBlocked True if the account is blocked + /// @return isSanctioned True if the account is sanctioned, always false if not sanctions oracle is set function isBlockedOrSanctioned(address _account) public view returns (bool isBlocked, bool isSanctioned) { address sanctionsOracle = StakingContractStorageLib.getSanctionsOracle(); if (sanctionsOracle != address(0)) { @@ -810,6 +817,9 @@ contract StakingContract { StakingContractStorageLib.getExitRequestMap().value[_publicKeyRoot] = _value; } + /// @notice Function to emit the ExitRequest event for each public key + /// @param publicKeys Concatenated public keys + /// @param owner Address of the expected owner of the public keys function _requestExits(bytes calldata publicKeys, address owner) internal { if (publicKeys.length % PUBLIC_KEY_LENGTH != 0) { revert InvalidPublicKeys(); @@ -984,7 +994,6 @@ contract StakingContract { address _dispatcher ) internal { bytes32 publicKeyRoot = _getPubKeyRoot(_publicKey); - address withdrawer = _getWithdrawer(publicKeyRoot); _revertIfSanctioned(msg.sender); bytes32 feeRecipientSalt = sha256(abi.encodePacked(_prefix, publicKeyRoot)); address implementation = StakingContractStorageLib.getFeeRecipientImplementation(); @@ -1002,7 +1011,7 @@ contract StakingContract { } } - function _revertIfSanctionedOrBlocked(address account) internal { + function _revertIfSanctionedOrBlocked(address account) internal view { address sanctionsOracle = StakingContractStorageLib.getSanctionsOracle(); if (sanctionsOracle != address(0)) { if (ISanctionsOracle(sanctionsOracle).isSanctioned(account)) { @@ -1014,7 +1023,7 @@ contract StakingContract { } } - function _revertIfSanctioned(address account) internal { + function _revertIfSanctioned(address account) internal view { address sanctionsOracle = StakingContractStorageLib.getSanctionsOracle(); if (sanctionsOracle != address(0)) { if (ISanctionsOracle(sanctionsOracle).isSanctioned(account)) { diff --git a/src/test/StakingContract.t.sol b/src/test/StakingContract.t.sol index 1719bc1..479f107 100644 --- a/src/test/StakingContract.t.sol +++ b/src/test/StakingContract.t.sol @@ -2051,6 +2051,7 @@ contract StakingContractBehindProxyTest is Test { SanctionsOracle oracle; + address internal proxyAdmin = address(42); event ExitRequest(address caller, bytes pubkey); function setUp() public { @@ -2065,17 +2066,17 @@ contract StakingContractBehindProxyTest is Test { address cldImpl = address(new ConsensusLayerFeeDispatcher(1)); address stakingContractImpl = address(new StakingContract()); - stakingContract = StakingContract(payable(address(new TUPProxy(stakingContractImpl, address(12345), "")))); + stakingContract = StakingContract(payable(address(new TUPProxy(stakingContractImpl, proxyAdmin, "")))); eld = ExecutionLayerFeeDispatcher( payable( - address(new TUPProxy(eldImpl, address(1), abi.encodeWithSignature("initELD(address)", stakingContract))) + address(new TUPProxy(eldImpl, proxyAdmin, abi.encodeWithSignature("initELD(address)", stakingContract))) ) ); cld = ConsensusLayerFeeDispatcher( payable( - address(new TUPProxy(cldImpl, address(1), abi.encodeWithSignature("initCLD(address)", stakingContract))) + address(new TUPProxy(cldImpl, proxyAdmin, abi.encodeWithSignature("initCLD(address)", stakingContract))) ) ); @@ -2178,6 +2179,7 @@ contract StakingContractBehindProxyTest is Test { } function test_deposit_withsanctions_senderSanctioned(address user) public { + vm.assume(user != proxyAdmin); oracle.setSanction(user, true); vm.prank(admin); @@ -2192,6 +2194,8 @@ contract StakingContractBehindProxyTest is Test { } function test_deposit_withSanctions_SenderClear(address user) public { + vm.assume(user != proxyAdmin); + vm.prank(admin); stakingContract.setSanctionsOracle(address(oracle)); @@ -2203,6 +2207,8 @@ contract StakingContractBehindProxyTest is Test { } function test_deposit_BlockedUser(address user) public { + vm.assume(user != proxyAdmin); + vm.prank(admin); stakingContract.blockAccount(user, "");