Q2 2026 Security & Compliance Report67 incidents, $764M in losses, 88% from operational failures.
Get the report →

Audit name:

[SCA] vAPI Network | SC Audit | Jul2026

Date:

Aug 20, 2026

Table of Content

Introduction
Audit Summary
System Overview
Potential Risks
Findings
Appendix 1. Definitions
Appendix 2. Scope
Appendix 3. Additional Valuables
Disclaimer

Want a comprehensive audit report like this?

Introduction

We express our gratitude to the vAPI Network team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.

A fixed-supply ERC-20 and a Uniswap V4 swap-fee hook are deployed on Base. Swaps on allowlisted token-pair pools are taxed up to 3%, with fees collected in the project token and forwarded to a treasury.

Document

NameSmart Contract Code Review and Security Analysis Report for vAPI Network
Audited ByIvan Bondar
Approved ByKornel Światłowski
Websitehttps://vapinetwork.ai
Changelog05/08/2026 - Preliminary Report
20/08/2026 - Final Report
PlatformBase
LanguageSolidity
TagsFungible Token; Permit Token; Signatures; Automated Market Maker (AMM); ERC20
Methodologyhttps://docs.hacken.io/methodologies/smart-contracts
  • Document

    Name
    Smart Contract Code Review and Security Analysis Report for vAPI Network
    Audited By
    Ivan Bondar
    Approved By
    Kornel Światłowski
    Changelog
    05/08/2026 - Preliminary Report
    20/08/2026 - Final Report
    Platform
    Base
    Language
    Solidity
    Tags
    Fungible Token; Permit Token; Signatures; Automated Market Maker (AMM); ERC20

Review Scope

Repositoryhttps://github.com/vAPI-Network/token
Initial Commit281ba94
Remediation Commit (fee in project token)372514c (audit/hacken-remediation)
Remediation Commit (fee in pair currency, ETH)f3f051d (explore/eth-fee-redesign)
  • Review Scope

    Initial Commit
    281ba94
    Remediation Commit (fee in project token)
    372514c (audit/hacken-remediation)
    Remediation Commit (fee in pair currency, ETH)
    f3f051d (explore/eth-fee-redesign)

Audit Summary

10Total Findings
7Resolved
2Accepted
1Mitigated

The system users should acknowledge all the risks summed up in the risks section of the report

Documentation quality

  • Functional requirements are partially covered in the repository README and contract-level NatSpec.

  • No dedicated external specification describes system architecture, operational procedures, or Uniswap V4 integration assumptions.

  • Technical description of FeeHook fee-direction handling, registry gating, and launch-guard behavior is provided via extensive NatSpec.

  • NatSpec comments are present and generally complete for public, owner-only, and complex internal hook functions.

Code quality

  • Standard OpenZeppelin patterns (ERC20, ERC20Burnable, ERC20Permit, Ownable2Step) are utilized.

  • Uniswap V4 BaseHook inheritance and PoolManager callback patterns are utilized for fee collection.

  • Contracts are non-upgradeable; proxy and storage-gap patterns are not used.

  • The development environment is configured (Foundry, pinned dependencies, deployment scripts, and CI).

Test coverage

Code coverage of the project is 95.24% (branch coverage).

  • Deployment and basic user interactions are covered with tests.

  • Negative cases and edge conditions are covered across unit, fuzz, invariant, and Base fork suites.

  • Multi-user scenarios (token transfers, ownership handoff, launch-guard stress) are covered, though some complex concurrent cross-role sequences remain limited to the fork suite.

System Overview

The system comprises two non-upgradeable contracts with no proxy pattern. Token is a standalone ERC-20 with a single mint at construction to a designated recipient and no privileged surface afterward. Supply is fixed at TOTAL_SUPPLY and may only decrease through burns. EIP-2612 permits are supported for gasless approvals. Ordinary transfers and off-pool integrations are not taxed by the token itself.

FeeHook is a Uniswap V4 BaseHook that attaches to pools formed by exactly one allowlisted project token and one allowlisted pair currency. Fees are always taken in the pool's token side and transferred to the treasury via poolManager.take. Charging occurs in _beforeSwap when the token is the specified currency and in _afterSwap when it is unspecified, covering exact-in and exact-out paths. Owner-managed registries (allowedTokens, allowedPairs) gate pool initialization through _beforeInitialize; accepted pools record poolFeeToken, so later delisting only blocks new initializations. lockLists freezes both lists permanently. Per-token feeThreshold accounting can auto-disable fees once cumulative collection reaches the threshold. feeExempt exempts designated caller contracts (V4 routers), and a one-time launch guard per token restricts early swaps by priority fee range and caller allowlist until a buy budget is exhausted or the guard is ended. Ownership uses Ownable2Step; renounceOwnership is disabled.

During remediation the fee leg was split into two alternative implementations of FeeHook, each delivered as a separate commit and each collecting the fee on one side of the pool. The token-side variant keeps charging on the pool's project-token side; the pair-side variant charges in the pool's counterpart currency, typically native ETH, and keys the fee accumulator and its shutoff threshold by both project token and fee currency rather than by token alone. Both variants also replace the callback-time poolManager.take described above with poolManager.mint, crediting the fee to the treasury as an ERC-6909 claim that the treasury redeems separately. Registry, launch-guard, and ownership surfaces are identical in both, and one variant is intended for deployment.

Files in Scope

  • Token.sol — Fixed-supply ERC-20 implementing OpenZeppelin ERC20, ERC20Burnable, and ERC20Permit. The constructor mints TOTAL_SUPPLY to a non-zero recipient; holders and approved spenders may reduce supply via burn and burnFrom.

  • FeeHook.sol — Uniswap V4 hook that charges configurable swap fees (capped at MAX_FEE) on allowlisted token-pair pools, routes proceeds to the treasury, and exposes owner controls for registries, fees, exemptions, launch guard, and two-step ownership transfer.

Privileged roles

  • Token.sol

    • No privileged roles exist after deployment. The constructor mints the fixed supply to a recipient address, which is an initial token holder only and not an on-chain admin role.

  • FeeHook.sol

    • owner (inherited from Ownable2Step / Ownable): Controls registry, fee configuration, launch-guard settings, and two-step ownership transfer. Ownership renunciation is permanently disabled.

      • Can call setTokenAllowed to allow or disallow project tokens (reverts when lists are locked).

      • Can call setPairAllowed to allow or disallow pair currencies, including address(0) for ETH (reverts when lists are locked).

      • Can call lockLists to permanently freeze both allowlists.

      • Can call setFee to update feeBps (bounded by MAX_FEE of 300).

      • Can call setFeeThreshold to set a per-token auto-disable collection threshold.

      • Can call setTreasury to update the validated fee recipient.

      • Can call setFeeExempt to exempt or un-exempt caller contracts from the fee.

      • Can call setLaunchGuard to arm a token's launch guard once before its first pool.

      • Can call setFeeRange to set the launch-guard priority fee range.

      • Can call setLaunchCallerAllowed to manage the launch-guard caller allowlist.

      • Can call endLaunchGuard to end a token's launch guard early (one-way).

      • Can call transferOwnership to nominate a new owner (two-step handoff).

      • Can call acceptOwnership (as pending owner) to accept ownership (two-step handoff).

      • Can call renounceOwnership, which always reverts with RenounceDisabled.

Potential Risks

Treasury and fee redemption outside the boundary: treasury is an owner-set address, validated only against the zero address, the hook itself, the PoolManager, and registry members. Because remediation credits fees as ERC-6909 claims on the PoolManager, realising them requires the treasury to burn those claims inside a PoolManager unlock, which an EOA or Safe can only do by authorising a redeemer contract through IERC6909Claims.setOperator. Neither the treasury account nor any redeemer contract is part of this review, so whether collected fees can be withdrawn, and in which currency the treasury is able to hold them, rests on configuration outside the audited boundary.

Uniswap V4 BaseHook and PoolManager dependency: FeeHook inherits BaseHook from v4-periphery, binds to IPoolManager from v4-core, and routes fees exclusively through poolManager.take inside _collectFee, which remediation replaced with poolManager.mint in both variants. Pool acceptance, swap deltas, and fee extraction rely on that external callback framework (getHookPermissions, _beforeInitialize, _beforeSwap, _afterSwap). Defects, unavailability, or currency-accounting changes in the Uniswap V4 hook or PoolManager path would directly affect fee charging, launch-guard enforcement, and delivery to treasury.

Coupling to Uniswap V4 swap lifecycle: Swap fees and launch-guard checks execute only inside Uniswap V4 pool callbacks for pools that pass _beforeInitialize registry checks (allowedTokens, allowedPairs, poolFeeToken). Ordinary ERC-20 transfers of Token are untaxed; all fee and antisnipe behavior is inseparable from V4 pool initialization and PoolManager.swap caller semantics (sender is the router contract, not the end-user EOA).

Fixed total supply determined at construction: Token defines TOTAL_SUPPLY as the constant 100_000_000e18 and mints that entire amount once in the constructor to the recipient parameter, with no subsequent mint path. Name, symbol, and initial holder are constructor inputs; after deployment, circulating supply can only decrease through ERC20Burnable burns. Misallocation of the initial recipient or incorrect name/symbol at deploy time is permanent for the minted supply distribution.

Owner-managed fee and launch caller allowlists: FeeHook maintains feeExempt and launchCallerAllowed, both writable only by the owner via setFeeExempt and setLaunchCallerAllowed. feeExempt causes an early return at the top of _beforeSwap (and skips fee charging in _afterSwap), so an exempt V4 sender pays no fee and is also never launch-gated. A non-empty launchCallerAllowed registry (launchAllowedCallers != 0) restricts buys while launchGuardActive is true; an empty registry disables only that caller gate, while any configured priority-fee floor or cap still applies. Incorrect exemption of a public router enables fee-free and guard-free swaps for all users of that router.

Immediate owner control without on-chain delay: The FeeHook owner can call setFee, setTreasury, setFeeThreshold, setFeeExempt, setTokenAllowed, setPairAllowed, setFeeRange, setLaunchCallerAllowed, endLaunchGuard, and lockLists in the same transaction that invokes each setter, with no on-chain timelock. setLaunchGuard is likewise immediate when callable, but only before the token's first accepted pool and only once. Fee rate (up to MAX_FEE), treasury destination, per-token shutoff thresholds, registry membership until lock, and global priority-fee bounds therefore take effect with no mandatory notice window. After launch, mid-flight reshaping of gating is limited to setFeeRange, setLaunchCallerAllowed, and one-way endLaunchGuard, not re-arming the buy budget.

Multi-sig recommended but not enforced: Constructor NatSpec for FeeHook recommends a Safe multisig as _owner, yet the contract accepts any non-zero address and performs no on-chain multi-signature or threshold check. Deployment may therefore leave fee, treasury, registry, and launch-guard powers under a single EOA. Off-chain custody choices cannot be verified from the in-scope bytecode alone.

Single administrative point of failure on FeeHook: Operational control of allowed tokens and pairs, fee rate, treasury, fee exemptions, launch-guard budgets, launch callers, and priority-fee range concentrates in the FeeHook owner. Loss, coercion, or compromise of that key or controlling contract can halt intended administration or force adversarial reconfiguration of all listed pools' fee and launch behavior. Token itself exposes no post-deployment admin surface.

Owner key liveness as ongoing dependency: renounceOwnership on FeeHook is overridden to revert with RenounceDisabled, so ownership cannot be burned away. Continued correct operation of fee updates, treasury rotation, and optional early endLaunchGuard therefore requires the owner key or owner contract to remain available and uncompromised for the lifetime of mutable configuration.

Count-based antisnipe budget can be burned by dust buys: Each token's launch guard is armed once via setLaunchGuard with a fixed launchGuardBuys budget; successful non-exempt buys that pass _checkLaunchBuy increment launchBuyCount until the budget is exhausted or endLaunchGuard ends it. Rejected buys revert and do not consume budget, but successful minimal buys through an allowed caller permanently advance the counter. A determined actor can exhaust the guard at gas, tip, and dust cost, after which priority-fee and caller checks permanently cease for that token.

One-way freezes and permanent guard termination: lockLists permanently sets listsLocked, after which setTokenAllowed and setPairAllowed always revert with ListsFrozen. endLaunchGuard sets launchGuardEnded for a token and cannot be undone; setLaunchGuard is set-once and unavailable after tokenHasPool is true. Premature locking freezes the registry against future tokens or pairs, and premature guard termination removes antisnipe protections with no re-arm path.

Partial fills rejected on the fee-specified swap path: When the fee currency is the swap's specified currency, _beforeSwap charges fee on the full requested amountSpecified, and _afterSwap reverts PartialFillNotSupported unless the realised specified-side delta matches that amount plus the fee. A fill an unmodified V4 pool would truncate is therefore rejected outright, which is protective rather than a defect, since V4 applies an _afterSwap return delta to the unspecified currency and the pre-charge cannot be refunded. The protected cells follow the fee side, so the pair-side variant moves the rejection onto exact-input buys, the ordinary retail path, where a buy exceeding pool depth reverts even under the canonical router's unbounded price limit. The contract NatSpec documents the behavior, the retail-path consequence included.

Findings

Code
Title
Status
Severity
F-2026-1880Callback-Time Fee Withdrawal Blocks Token Sells When PoolManager Inventory Is Thin
fixed

Medium
F-2026-1880Launch-Guard Budget Can Be Exhausted by Zero-Fee Dust Buys in a Single Transaction
accepted

Medium
F-2026-1880Permissionless Initialization Permanently Blocks Arming of a Token's Launch Guard
fixed

Medium
F-2026-1880Third Parties Can Advance the Token-Wide Fee Threshold and Disable Fees on Intended Pools
mitigated

Low
F-2026-1898Missing Key Validation In Fee Threshold Setter Prevents Fee Shutoff
accepted

Low
F-2026-1881Exact-Output Trades Pay a Lower Effective Fee Than Exact-Input Trades
fixed

Observation
F-2026-1881Canonical Pool Initialization Can Be Front-Run
fixed

Observation
F-2026-1881Registry Documentation Overstates Pool-Level Admission
fixed

Observation
F-2026-1881Dynamic-Fee Pools Can Attach and Remain at Zero LP Fee
fixed

Observation
F-2026-1880Router Allowlisting Cannot Enforce the Documented Front-End-Only Access Rule
fixed

Observation
1-10 of 10 findings

Identify vulnerabilities in your smart contracts.

Appendix 1. Definitions

Severities

When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.

Reference on how risk scoring is done is available through the repository in our Github organization:

Severity

Description

Critical
Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

High
High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

Medium
Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

Low
Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
  • Severity

    Critical

    Description

    Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

    Severity

    High

    Description

    High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

    Severity

    Medium

    Description

    Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

    Severity

    Low

    Description

    Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.

Potential Risks

The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.

Appendix 2. Scope

The scope of the project includes the following smart contracts from the provided repository:

Scope Details

Repositoryhttps://github.com/vAPI-Network/token
Initial Commit281ba94dad1c8d00e1f807bb931c22381cc5f756
Remediation Commit (fee in project token)372514ca99250590764c9cb9f101ca90181de2bf (audit/hacken-remediation)
Remediation Commit (fee in pair currency, ETH)f3f051d05eeddd5943eb2c2e419c1ec2ac7a68f2 (explore/eth-fee-redesign)
WhitepaperN/A
RequirementsREADME.md; NatSpec
Technical RequirementsREADME.md; NatSpec
  • Scope Details

    Initial Commit
    281ba94dad1c8d00e1f807bb931c22381cc5f756
    Remediation Commit (fee in project token)
    372514ca99250590764c9cb9f101ca90181de2bf (audit/hacken-remediation)
    Remediation Commit (fee in pair currency, ETH)
    f3f051d05eeddd5943eb2c2e419c1ec2ac7a68f2 (explore/eth-fee-redesign)
    Whitepaper
    N/A
    Requirements
    README.md; NatSpec
    Technical Requirements
    README.md; NatSpec

Assets in Scope

src
FeeHook.sol - src › FeeHook.sol
Token.sol - src › Token.sol

Appendix 3. Additional Valuables

Additional Recommendations

The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.

To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:

  • Detecting changes to ownership or critical permissions.

  • Monitoring large or unexpected transactions and minting events.

  • Pausing operations when irregularities are identified.

These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.

Frameworks and Methodologies

This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment , and the Penetration Testing Execution Standard (PTES) , These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.

Disclaimer