Bastion Wallet · Smart Contract Security AssessmentBastion Wallet Client Hub

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.

EthereumSoliditySmart Contract Code Review2024-03-01github.com/bastion-walletZealynx methodology
Total findings
10
10 fixed
Critical
00
High
02
Medium
03
Low + Info
05
02

Scope

4 files · 253 SLOC
Repository
Initial commit
75b205367015
Final commit
79cddfeb6070
Platform
Ethereum · Solidity
Methodology
File
src/subscriptions/Initiator.sol
src/subscriptions/SubExecutor.sol
src/interfaces/IInitiator.sol
src/subscriptions/ISubExecutor.sol
03

Findings

click any row for the full write-up
04

Key Findings

  • Logic flaw in subscription handling lets Initiator functions be called by both EOAs and SCAs. When an executor is an EOA calling Initiator directly without going through the Bastion SDK, the subscriber becomes the EOA address rather than the SubExecutor mapping, so subscriptions registered from the Initiator cannot be modified, payments cannot be initiated, and removals fail.
  • Incorrect ERC-20 token transfer in _processERC20Payment() uses transferFrom instead of transfer. The SubExecutor holds the funds, so transferFrom(address(this), sub.initiator, sub.amount) reverts with "insufficient allowance" and prevents legitimate payment execution.
  • Hardcoded validAfter blocks single-batch registration and first payment. registerSubscription() sets validAfter to block.timestamp while initiatePayment() requires validAfter < block.timestamp, making both functions mutually exclusive within the same block (incompatible with Bastion's batched userOperations).
  • Subscription token type cannot be distinguished safely. erc20TokensValid is 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 the subscribers array until getSubscribers() exhausts gas.
05

Team & approval

Lead Auditor
Shieldify Security
Co-auditor
Zealynx Security
06

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.

Download PDF (27p)
ZEALYNX SECURITY · published 2024-03-01
10 findings · Solidity

oog
zealynx

Smart Contract Security Digest

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

© 2026 Zealynx