Bastion Wallet Account Abstraction SDK
Zealynx co-audited Bastion Wallet's ERC-4337 Account Abstraction SDK alongside Shieldify Security, reviewing the Initiator and SubExecutor subscription contracts across 253 nSLOC and 4 files. The 6-day review by five researchers (three manual reviewers, two on fuzz testing with Halmos, Echidna and Foundry) identified 10 issues including 2 High-severity logic flaws in the subscription handling functions and the ERC-20 transfer flow. All findings were acknowledged and fixed as suggested.
Scope
4 files · 253 SLOCFindings
click any row for the full write-upKey Findings
- Logic flaw in subscription handling lets
Initiatorfunctions be called by both EOAs and SCAs. When an executor is an EOA callingInitiatordirectly without going through the Bastion SDK, the subscriber becomes the EOA address rather than the SubExecutor mapping, so subscriptions registered from theInitiatorcannot be modified, payments cannot be initiated, and removals fail. - Incorrect ERC-20 token transfer in
_processERC20Payment()usestransferFrominstead oftransfer. The SubExecutor holds the funds, sotransferFrom(address(this), sub.initiator, sub.amount)reverts with "insufficient allowance" and prevents legitimate payment execution. - Hardcoded
validAfterblocks single-batch registration and first payment.registerSubscription()setsvalidAftertoblock.timestampwhileinitiatePayment()requiresvalidAfter < block.timestamp, making both functions mutually exclusive within the same block (incompatible with Bastion's batched userOperations). - Subscription token type cannot be distinguished safely.
erc20TokensValidis true whenever a non-zero token address is supplied, so a malicious or non-standard token contract is accepted as if it were a standard ERC-20, leading to unexpected behavior in_processNativePayment()vs_processERC20Payment()branching. - Unbounded subscription registration enables DoS.
registerSubscription()has no per-user cap, allowing a single subscriber to register unlimited entries and grow thesubscribersarray untilgetSubscribers()exhausts gas.
Team & approval
Disclaimer
This audit is not an endorsement and does not constitute investment advice. Zealynx reviewed the codebase at the commits listed in section 02 over the engagement window. Findings are limited to issues identified within that scope and do not preclude the existence of other vulnerabilities. Subsequent code changes are not covered by this report unless the engagement is explicitly extended.

