Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/core/SSVBasedApps.sol
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,7 @@ contract SSVBasedApps is
_delegateTo(SSVCoreModules.SSV_PROTOCOL_MANAGER);
}

function updateDisabledFeatures(
uint32 disabledFeatures
) external onlyOwner {
function updateDisabledFeatures(uint32 value) external onlyOwner {
_delegateTo(SSVCoreModules.SSV_PROTOCOL_MANAGER);
}

Expand Down
16 changes: 7 additions & 9 deletions src/core/modules/StrategyManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pragma solidity 0.8.29;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ReentrancyGuardTransient } from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";

import { ValidationLib, MAX_PERCENTAGE, ETH_ADDRESS } from "@ssv/src/core/libraries/ValidationLib.sol";
import { ICore } from "@ssv/src/core/interfaces/ICore.sol";
Expand Down Expand Up @@ -198,7 +197,7 @@ contract StrategyManager is ReentrancyGuardTransient, IStrategyManager {

s.accountBAppStrategy[msg.sender][bApp] = strategyId;

if (_isBApp(bApp)) {
if (_isContract(bApp)) {
bool success = IBasedApp(bApp).optInToBApp(
strategyId,
tokens,
Expand All @@ -217,12 +216,11 @@ contract StrategyManager is ReentrancyGuardTransient, IStrategyManager {
);
}

/// @notice Function to check if an address uses the correct bApp interface
/// @notice Function to check if an address is a contract
/// @param bApp The address of the bApp
/// @return True if the address uses the correct bApp interface
function _isBApp(address bApp) private view returns (bool) {
return
ERC165Checker.supportsInterface(bApp, type(IBasedApp).interfaceId);
/// @return True if the address is a contract
function _isContract(address bApp) private view returns (bool) {
return bApp.code.length > 0;
}

/// @notice Deposit ERC20 tokens into the strategy
Expand Down Expand Up @@ -774,7 +772,7 @@ contract StrategyManager is ReentrancyGuardTransient, IStrategyManager {
bool exit;
bool success;
uint32 obligationPercentage;
if (_isBApp(bApp)) {
if (_isContract(bApp)) {
(success, receiver, exit) = IBasedApp(bApp).slash(
strategyId,
token,
Expand All @@ -797,7 +795,7 @@ contract StrategyManager is ReentrancyGuardTransient, IStrategyManager {
strategyTokenShares
);
} else {
// Only the bApp EOA or non-compliant bapp owner can slash
// Only the bApp EOA can slash
if (msg.sender != bApp) revert InvalidBAppOwner(msg.sender, bApp);
receiver = bApp;
_exitStrategy(s, strategyId, bApp, token);
Expand Down
4 changes: 1 addition & 3 deletions src/middleware/interfaces/IBasedApp.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.29;

import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import { ICore } from "@ssv/src/core/interfaces/ICore.sol";

interface IBasedApp is IERC165 {
interface IBasedApp {
function optInToBApp(
uint32 strategyId,
address[] calldata tokens,
Expand All @@ -23,7 +22,6 @@ interface IBasedApp is IERC165 {
address sender,
bytes calldata data
) external returns (bool success, address receiver, bool exit);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
function updateBAppMetadataURI(string calldata metadataURI) external;
function updateBAppTokens(
ICore.TokenConfig[] calldata tokenConfigs
Expand Down
17 changes: 0 additions & 17 deletions src/middleware/modules/core+roles/AccessControlBasedApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity 0.8.29;

import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import { IBasedApp } from "@ssv/src/middleware/interfaces/IBasedApp.sol";
import { BasedAppCore } from "@ssv/src/middleware/modules/core/BasedAppCore.sol";
Expand Down Expand Up @@ -66,20 +65,4 @@ abstract contract AccessControlBasedApp is BasedAppCore, AccessControl {
metadataURI
);
}

/// @notice Checks if the contract supports the interface
/// @param interfaceId interface id
/// @return isSupported if the contract supports the interface
function supportsInterface(
bytes4 interfaceId
)
public
pure
override(AccessControl, BasedAppCore)
returns (bool isSupported)
{
return
interfaceId == type(IBasedApp).interfaceId ||
interfaceId == type(IERC165).interfaceId;
}
}
12 changes: 0 additions & 12 deletions src/middleware/modules/core+roles/OwnableBasedApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity 0.8.29;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import { IBasedApp } from "@ssv/src/middleware/interfaces/IBasedApp.sol";
import { BasedAppCore } from "@ssv/src/middleware/modules/core/BasedAppCore.sol";
Expand Down Expand Up @@ -48,15 +47,4 @@ abstract contract OwnableBasedApp is Ownable, BasedAppCore {
metadataURI
);
}

/// @notice Checks if the contract supports the interface
/// @param interfaceId interface id
/// @return isSupported if the contract supports the interface
function supportsInterface(
bytes4 interfaceId
) public pure override(BasedAppCore) returns (bool isSupported) {
return
interfaceId == type(IBasedApp).interfaceId ||
interfaceId == type(IERC165).interfaceId;
}
}
13 changes: 0 additions & 13 deletions src/middleware/modules/core/BasedAppCore.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.29;

import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import { IBasedApp } from "@ssv/src/middleware/interfaces/IBasedApp.sol";

import { IBasedAppManager } from "@ssv/src/core/interfaces/IBasedAppManager.sol";
Expand Down Expand Up @@ -135,17 +133,6 @@ abstract contract BasedAppCore is IBasedApp {
return (true, address(this), true);
}

/// @notice Checks if the contract supports the interface
/// @param interfaceId interface id
/// @return true if the contract supports the interface
function supportsInterface(
bytes4 interfaceId
) public pure virtual returns (bool) {
return
interfaceId == type(IBasedApp).interfaceId ||
interfaceId == type(IERC165).interfaceId;
}

// Receive function to accept plain Ether transfers
receive() external payable virtual {}
}
27 changes: 0 additions & 27 deletions test/modules/BasedAppsManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ pragma solidity 0.8.29;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import { UtilsTest } from "@ssv/test/helpers/Utils.t.sol";
import { IBasedAppManager, IBasedApp } from "@ssv/test/helpers/Setup.t.sol";
Expand Down Expand Up @@ -434,31 +432,6 @@ contract BasedAppsManagerTest is UtilsTest {
}
}

function testSupportInterface() public {
vm.startPrank(USER1);
for (uint256 i = 0; i < bApps.length; i++) {
bool success = bApps[i].supportsInterface(
type(IBasedApp).interfaceId
);
assertEq(success, true, "supportsInterface based app");
bool failed = bApps[i].supportsInterface(
type(IBasedAppManager).interfaceId
);
assertEq(
failed,
false,
"does not supportsInterface based app manager"
);
bool failed2 = bApps[i].supportsInterface(type(IERC20).interfaceId);
assertEq(failed2, false, "does not supportsInterface");
bool success2 = bApps[i].supportsInterface(
type(IERC165).interfaceId
);
assertEq(success2, true, "does supportsInterface of IERC165");
}
vm.stopPrank();
}

function testUpdateBAppTokens() public {
testRegisterBApp();
(
Expand Down
2 changes: 1 addition & 1 deletion test/modules/ProtocolManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ contract ProtocolManagerTest is Setup, Ownable2StepUpgradeable {
}

/// @notice By default, no features should be disabled
function testDefaultDisabledFeaturesIsZero() public {
function testDefaultDisabledFeaturesIsZero() public view {
assertEq(
proxiedManager.disabledFeatures(),
0,
Expand Down
29 changes: 3 additions & 26 deletions test/modules/SlashingManager.eoa.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ contract SlashingManagerEOATest is StrategyManagerTest {
proxiedManager.withdrawETHSlashingFund(slashAmount);
}

// Slash Non Compatible BApp
// Slash Non Compatible BApp, does not implement the slash function inside the contract
function testSlashNonCompatibleBApp(uint32 slashPercentage) public {
uint32 percentage = 9000;
uint256 depositAmount = 100_000;
Expand All @@ -266,25 +266,8 @@ contract SlashingManagerEOATest is StrategyManagerTest {
depositAmount
);
vm.prank(USER1);
vm.expectEmit(true, true, true, true);
emit IStrategyManager.StrategySlashed(
STRATEGY1,
address(nonCompliantBApp),
token,
slashPercentage,
address(nonCompliantBApp)
);
vm.expectRevert();
nonCompliantBApp.slash(STRATEGY1, token, slashPercentage);
uint256 newStrategyBalance = depositAmount - slashAmount;
checkTotalSharesAndTotalBalance(
STRATEGY1,
token,
depositAmount,
newStrategyBalance
);
checkAccountShares(STRATEGY1, USER2, token, depositAmount);
checkSlashableBalance(STRATEGY1, address(nonCompliantBApp), token, 0);
checkSlashingFund(address(nonCompliantBApp), token, slashAmount);
}

function testRevertSlashNonCompatibleBAppWithNonOwner() public {
Expand All @@ -300,13 +283,7 @@ contract SlashingManagerEOATest is StrategyManagerTest {
IERC20(erc20mock),
depositAmount
);
vm.expectRevert(
abi.encodeWithSelector(
IStrategyManager.InvalidBAppOwner.selector,
USER2,
address(nonCompliantBApp)
)
);
vm.expectRevert();
proxiedManager.slash(
STRATEGY1,
address(nonCompliantBApp),
Expand Down