Assessment reports>Hyperbeat Pay>Informational findings>Functions allow interaction with services removed from registry
Category: Business Logic

Functions allow interaction with services removed from registry

Informational Impact
Low Severity
High Likelihood

Description

Several functions validate services using only the local _approvedServices[service] mapping without checking the ServiceRegistry, allowing interaction with previously approved services that have been removed from the registry:

function getBalance(address service, address asset) external view returns (uint256) {
!   if (!_approvedServices[service]) revert ManagementAccountErrors.ServiceNotApproved(service);
    [...]
}

function requestCreditMode(address service, address collateralToken) external onlyOwner {
!   if (!_approvedServices[service]) revert ManagementAccountErrors.ServiceNotApproved(service);
    [...]
}

function requestCreditModeChange(address newService, address newCollateralToken) external onlyOwner {
!   if (!_approvedServices[newService]) revert ManagementAccountErrors.ServiceNotApproved(newService);
    [...]
}

This creates inconsistent behavior where some functions (like executeServiceAction) properly validate registry membership using _validateRegisteredService, while these functions only check local approval status.

Impact

Accounts can continue interacting with delisted or compromised services through getBalance, requestCreditMode, requestCreditModeChange, and executeModeChange. This undermines the registry's purpose as a centralized control point for managing active services and creates security risks if services are removed due to vulnerabilities or deprecation.

Recommendations

Update these functions to use _validateRegisteredService for proper validation:

function getBalance(address service, address asset) external view returns (uint256) {
-    if (!_approvedServices[service]) revert ManagementAccountErrors.ServiceNotApproved(service);
+    _validateRegisteredService(service);
    [...]
 }

 function requestCreditMode(address service, address collateralToken) external onlyOwner {
-    if (!_approvedServices[service]) revert ManagementAccountErrors.ServiceNotApproved(service);
+    _validateRegisteredService(service);
     [...]
 }

 function requestCreditModeChange(address newService, address newCollateralToken) external onlyOwner {
-    if (!_approvedServices[newService]) revert ManagementAccountErrors.ServiceNotApproved(newService);
+    _validateRegisteredService(newService);
     [...]
 }

 function executeModeChange() external onlyOperator {
+    if (_pendingMode == AccountMode.CREDIT && _pendingCreditService != address(0)) {
+        _validateRegisteredService(_pendingCreditService);
+    }
     [...]
 }

Remediation

Zellic © 2025Back to top ↑