Assessment reports>Hyperbeat Pay>Low findings>Spending limit can exceed available settlement balance
Category: Business Logic

Spending limit can exceed available settlement balance

Low Impact
Low Severity
High Likelihood

Description

The increaseSettlementAllowance function allows owners to set spending limits that exceed their available settlement-token balance in SPENDING mode:

function increaseSettlementAllowance(uint256 additionalAmount) external override onlyOwner {
    if (additionalAmount == 0) revert ManagementAccountErrors.InvalidAmount(additionalAmount);

    _spendingLimit.settlementAllowance += additionalAmount;

    emit SettlementAllowanceIncreased(additionalAmount, _spendingLimit.settlementAllowance);
}

This creates an inconsistency with executeModeChange, which enforces that available balance must be greater than or equal to the spending limit when switching to SPENDING mode:

function executeModeChange() external onlyOperator {
    [...]
    // Enforce settlement token minimum when switching TO SPENDING mode
    if (_pendingMode == AccountMode.SPENDING && _spendingLimit.settlementAllowance > 0) {
        address settlementTokenAddress = _settlementToken();
        uint256 availableBalance = _availableBalance(settlementTokenAddress);
!       if (availableBalance < _spendingLimit.settlementAllowance) {
            revert ManagementAccountErrors.SettlementBalanceBelowSpendingLimit(
                availableBalance, _spendingLimit.settlementAllowance
            );
        }
    }
    [...]

Impact

Users in SPENDING mode can set spending limits that exceed their available settlement balance, violating the protocol's invariant that balance is greater than or equal to the spending limit in SPENDING mode. This creates several issues.

Off-chain payment processing systems relying on the spending limit to authorize card payments may approve transactions that fail during settlement, leading to payment failures and poor user experience.

Additionally, this inconsistency creates a confusing state where users can bypass balance checks by increasing their allowance while in SPENDING mode, even though they would be blocked from entering SPENDING mode with the same allowance/balance ratio.

Recommendations

Add validation to ensure the new spending limit does not exceed the available settlement balance in SPENDING mode:

function increaseSettlementAllowance(uint256 additionalAmount) external override onlyOwner {
     if (additionalAmount == 0) revert ManagementAccountErrors.InvalidAmount(additionalAmount);

+    uint256 newAllowance = _spendingLimit.settlementAllowance + additionalAmount;
+    address settlementTokenAddress = _settlementToken();
+    uint256 availableBalance = _availableBalance(settlementTokenAddress);
+    
+    if (_mode == AccountMode.SPENDING && newAllowance > availableBalance) {
+        revert ManagementAccountErrors.SettlementAllowanceExceedsBalance(newAllowance, availableBalance);
+    }

-     _spendingLimit.settlementAllowance += additionalAmount;
+     _spendingLimit.settlementAllowance = newAllowance;

     emit SettlementAllowanceIncreased(additionalAmount, _spendingLimit.settlementAllowance);
 }

Remediation

This issue has been acknowledged by Hyperbeat, and a fix was implemented in commit 8afead3e.

Zellic © 2025Back to top ↑