F-2024-0007·missing-validation

Incomplete subscriber removal logic in Initiator.sol contract

Fixedaccount-abstractionerc-4337subscriptiongithub.com/bastion-wallet
TL;DR

removeSubscription deletes the mapping entry but leaves the subscriber's address in the subscribers array, growing the array unboundedly and enabling a DoS on iterating callers.

Severity
LOW
Impact
LOW
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
LOW
Exploitability
MEDIUM
02Section · Description

Description

Registering a new subscription involves updating the subscriptionBySubscriber mapping and appending the subscriber's address to the subscribers array. However, the removeSubscription() method solely removes the subscriber's address from the mapping, leaving potentially invalid subscriptions untouched within the storage array. This oversight, coupled with the absence of a subscription count limit, poses a vulnerability that could be exploited to initiate a Denial of Service (DoS) attack.

solidity
/// @notice Removes a subscription for a subscriber
/// @param _subscriber Address of the subscriber
function removeSubscription(address _subscriber) public {
require(msg.sender == _subscriber, "Only the subscriber can remove a subscription");
delete subscriptionBySubscriber[_subscriber];
}
03Section · Impact

Impact

Stale entries accumulate in the subscribers array. Combined with the unlimited-registration finding, an attacker can grow the array unboundedly and gas-grief callers that iterate it.

04Section · Recommendation

Recommendation

Modify the removeSubscription() function to remove from the subscribers array and additionally, consider introducing a subscriptions count limit to prevent potential Denial of Service (DoS) attack.

diff
+ mapping(address => bool) public isSubscriber;
+ mapping(address => uint256) public subscriberByIndex;
function removeSubscription(address _subscriber) public {
require(msg.sender == _subscriber, "Only the subscriber can remove a subscription");
delete subscriptionBySubscriber[_subscriber];
+ uint256 index = subscriberByIndex[_subscriber];
+ address lastSubscriber = subscribers[subscribers.length - 1];
+ subscribers[index] = lastSubscriber;
+ subscriberByIndex[lastSubscriber] = index;
+ subscribers.pop();
}
05Section · Resolution

Resolution

Team Response: Acknowledged and fixed as suggested.

Status
Fixed
Fix commit
79cddfeb6070
F-2024-0007

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx