Virtuals Systems Global Limited

Virtuals Protocol Security Audit Overview | Cantina

Cantina Security Report

Organization

@virtuals

Engagement Type

Cantina Reviews

Period

-


Smart Contract Assessment for Virtuals Protocol

Virtuals Protocol is developing decentralized infrastructure for AI agents to interact, transact, and build autonomous economies onchain. Positioned as “The Wall Street for AI,” the protocol supports scalable agent coordination across blockchain environments.

This security audit was delivered through Cantina’s expert-managed review process, helping reinforce trust and reliability in emerging cross-chain agent architectures. The assessment supports long-term protocol resilience while aligning with security best practices across decentralized infrastructure.

In addition to security audits, Cantina offers protocols like Virtuals access to bug bounty programs, crowdsourced security competitions, incident response, and multisig security to ensure continuous protection and operational confidence.


Findings


Informational3 findings

  1. Lack of documentation for externally callable functions

    State

    New

    Severity

    Severity: Informational

    Submitted by

    Joran Honig


    Description

    Functions core to the functionality of the smart contract system do not have a company NatSpec documentation.

    Recommendation

    Introduce documentation for all functions that can be called externally. It's also worth considering adding similar documentation for other functions, as it helps improve maintainability and reduces cognitive load of the codebase.

    Furthermore, it can be beneficial to revisit the structure of the code base and grouping of functions. Grouping similar (and/or externally callable) functions together can have tremendous impact on the time it takes to understand and change the contract.

    Finally, introducing tests to execute the principal functionality of the contract will aid both as a form of documentation (tests demonstrate how the code is intended to function) and help discover unintended divergences in functionality between versions of the agent factory.

  2. Use custom errors to reduce bytecode size

    State

    New

    Severity

    Severity: Informational

    Submitted by

    Kankodu


    Description

    The codebase currently uses string-based revert statements to indicate errors. These strings increase the contract's bytecode size.

    Recommendation

    With the current version of Solidity, custom errors can be used with the require statement. Use them everywhere to reduce bytecode size.

  3. Inheritance of non-upgradable contracts

    State

    New

    Severity

    Severity: Informational

    Submitted by

    Joran Honig


    Description

    Upgradeable variants of contracts should be used when the contract is intended to be used in an upgradeable fashion.

    Currently the compiler will linearize the AccessControl constructor in the constructor of AgentFactoryV5. Note however that the impact is limited as the current version of AccessControlUpgradable does not have side effects.

    Similarly Genesis inherits AccessControlUpgradeable but inherits non-upgradable ReentrancyGuard.

    Recommendation

    Use upgradable versions and apply appropriate initializers. For example, use AccessControlUpgradeable and initialize the contract in AgentFactoryV5.

    For Genesis it's also worth considering explicitly inheriting from Initializable. This contract is implicitly inherited from AccessControlUpgradeable and used directly. In such cases an explicit dependency is advisable.

Gas Optimizations2 findings

  1. Gas savings in Genesis Contract Deployment

    State

    New

    Severity

    Severity: Gas optimization

    Submitted by

    Kankodu


    Description

    When the createGenesis function is called, a new Genesis contract is deployed. However, the contract is currently not being cloned using a minimal proxy pattern, which would significantly reduce the gas cost associated with deployment.

    Despite this, the Genesis contract is still made initializable. This forfeits the potential gas savings that could be achieved by marking many state variables as immutable since they do not change after initialization.

    Recommendation

    Either deploy a clone of the Genesis contract using a minimal proxy to reduce deployment costs, or initialize the state variables directly in the constructor. This will allow you to declare them as immutable, leading to lower gas usage when these variables are accessed later.

  2. Redundant checks on allowance and balance

    State

    New

    Severity

    Severity: Gas optimization

    Submitted by

    Joran Honig


    Description

    These checks are potentially redundant when safeTransferFrom() is used. Calls to safeTransferFrom should revert when a call to assetToken transferFrom reverts or returns an ERC20 compliant value indicating the transfer failed.

    Recommendation

    If assetToken follows the ERC20 specification then these checks can be removed with the benefit of reducing gas cost and contract size.