Web3 · Smart contract audit
Coinversa
softstack has completed 2 smart contract audits for Coinversa in March 2026, reporting 33 findings in total (4 high, 13 medium and 16 low), of which 29 were resolved or mitigated before the final reports. Every report is published in the softstack public audit archive.
Key facts
- Client
- Coinversa
- Audits completed
- 2
- Latest audit
- Type
- Smart contract audit
- Chains
- Canton, Solana, Ethereum
About the project
Coinversa provides on-chain market intelligence for applications, traders and AI agents, covering wallet performance, trading cohorts, liquidation risk and cross-market assets. Data is served through a REST API, WebSocket streams and a hosted MCP server for Hyperliquid. Coinversa Inc is incorporated in Delaware and covers the Canton, Solana and Ethereum ecosystems.
Findings
Combined across all 2 reviews softstack has completed for Coinversa. Each report is broken out below.
29 of 33 findings resolved before the final reports.
Reports
Newest first. Every report covers its own scope and commit.
Backend & Frontend Codebase Security smart contract audit
0Critical4High8Medium1Low0Informational13 of 13 resolved
Scope
Source repositorygithub.com/Coinversaa/backendComponents reviewed
1 module- See the published report for the file list
All 13 findings
ID Title Severity Status 6.2.1privyAuth GET Bypass: Inconsistent Auth Model The `privyAuth` middleware explicitly bypasses token verification for all GET, HEAD, and OPTIONS requests.
High fixed 6.2.2privyAuth No Ownership Check: Trading IDOR After verifying the Privy JWT, `privyAuth` sets `req.privyUser.userId` but never asserts that target wallet fields in the request (`address`, `masterAddress`, `fromAddress`) belong to that authenticated user.
High fixed 6.2.3Hardcoded PostgreSQL Credentials in Fallback Connection String The PostgreSQL connection pool is initialised with a hardcoded fallback connection string that contains live database credentials.
High fixed 6.2.4Notifications.jsx innerHTML XSS (Stored XSS Vector) The `Notifications.jsx` toast renderer builds the notification DOM by setting `toast.innerHTML` to a template literal that directly includes the `message` variable, which is populated from server- provided API error responses…
High fixed 6.2.5Canton Passkey Secret Stored Unencrypted in localStorage A passkey-derived cryptographic secret (`coinversaa-id-secret`) is stored unencrypted in `localStorage`. The developer left a TODO comment directly above the storage call acknowledging this is insecure.
Medium fixed 6.2.6Missing Security Hardening Middleware The Express backend is missing all standard security hardening middleware: no `helmet` (X- Powered-By header leaks Express framework/version, no Content-Security-Policy, HSTS, X-Frame- Options), no `express-rate-limit` (no brute-force…
Medium fixed 6.2.7JWT Tokens Never Expire `jwt.sign()` is called without an `expiresIn` option in `cantonService.ts`. Tokens created without an expiry never expire.
Medium fixed 6.2.8HTML Injection in Email Bodies The `/register-interest` endpoint and developer API access request handler interpolate user-supplied `name`, `email`, and `reasonForInterest` fields directly into HTML email templates sent to the admin mailbox.
Medium fixed 6.2.9WebSocket No maxPayload Limit (DoS Risk) The `/ws/hyperliquid` WebSocket server is created without a `maxPayload` option. The default `ws` library behaviour is to accept frames of unlimited size.
Medium fixed 6.2.10Auth Tokens in localStorage (Session Theft Risk) Auth tokens (`accessToken`, `privy:token`) are stored in `localStorage`, making them readable by any JavaScript on the page.
Medium fixed 6.2.11Vulnerable Dependencies: Backend (121 CVEs, 6 Critical) 121 CVEs found across 90 packages (6 critical, 58 high, 37 medium, 20 low). Critical packages `pbkdf2`, `sha.js`, `elliptic` are cryptographic libraries — vulnerabilities in these carry elevated risk given the blockchain/trading context.
Medium fixed 6.2.12Vulnerable Dependencies: Frontend (95 CVEs, 4 Critical) 95 CVEs found across 65 packages (4 critical, 46 high, 43 medium, 2 low).
Medium fixed 6.2.13Express X-Powered-By Header Disclosure Express sends `X-Powered-By: Express` in every HTTP response by default. This header advertises the framework to any observer, reducing the cost of reconnaissance for an attacker.
Low fixed Canton DAML Smart Contracts smart contract audit
0Critical0High5Medium15Low0Informational16 of 20 resolved
All 20 findings
ID Title Severity Status 6.2.1Operator Controls UserIdentity Mutations That Should Belong to the User UserIdentity is owned by `userParty`, but `LinkWallet`, `UnlinkWallet`, and `ArchiveIdentity` are all controlled by `operator`.
Medium fixed 6.2.2Core Records Lack Enforced Uniqueness in the Current Canton 3 Design `TransactionCommitment`, `UserStatistics`, and `TermsAcceptance` contain commented-out key declarations for the uniqueness properties the system appears to expect.
Medium fixed 6.2.4Terms Acceptance Is Not Enforced by the Transaction Workflow The reviewed DAML code does not link `TermsAcceptance` into `TransactionCommitment` creation or redemption.
Medium fixed 6.2.7Transaction Hash Validation Accepts Invalid Pending and EVM Forms `validateTxHash` accepts any `pending_`, `solana_pending_`, or `hl_` prefix with no remainder bounds, and accepts 66-character `0x` hashes without verifying that the payload is hexadecimal.
Low fixed 6.2.9sourceWallet Is Not Validated Against walletType in TransactionCommitment The `TransactionCommitment` ensure clause validates `txHash`, numeric fields, token symbols, and `dataHash`, but never validates `sourceWallet`.
Low fixed 6.2.14Same-State UpdateStatus Calls Can Still Change blockNumber `UpdateStatus` permits `Pending -> Pending`, `Confirmed -> Confirmed`, and `Failed -> Failed`, while also allowing `updatedBlockNumber` to overwrite `blockNumber`.
Low acknowledged 6.2.18signedMessage Is Not Bound to Wallet, Terms Version, or Terms Hash `signedMessage` is required to be non-empty, but the code never checks whether it corresponds to `walletAddress`, `termsVersion`, or `termsHash`.
Low fixed 6.2.3User Cannot Revoke Their Own Terms Acceptance The only mutating choice on `TermsAcceptance` is `RevokeAcceptance`, and it is controlled by `operator`. The user can query the record, but cannot change or revoke it.
Medium fixed 6.2.5Operator-Supplied acceptedAt Timestamp Is Unconstrained `acceptedAt` is a template field provided at creation time, but the `ensure` block does not validate it and no creation helper sets it from ledger time.
Medium fixed 6.2.6Wallet Address Validation Is Mostly Length-Based `validateWalletAddress` checks only minimal shape constraints. EVM requires `0x` plus total length 42, but does not verify hexadecimal characters.
Low fixed 6.2.8LinkWallet Does Not Verify Wallet Ownership `LinkWallet` checks formatting and wallet-count limits, but never proves that the user controls the wallet being attached.
Low acknowledged 6.2.10termsHash Checks Length but Not Hex Content `TermsAcceptance` only checks `Text.length termsHash == 64`. That enforces size, not SHA-256 hex encoding.
Low fixed 6.2.11LinkAuthKey Allows Duplicate Authentication Keys `LinkAuthKey` prepends a new `(authKey, encryptedKey)` pair but does not check whether the same key is already present.
Low fixed 6.2.12Redeem Does Not Enforce a Transaction-State Transition `Redeem` checks wallet linkage and one-time redemption, but it does not validate the current `status` and does not change `status` after redemption.
Low fixed 6.2.13ArchiveTransaction Allows Unilateral Record Deletion `ArchiveTransaction` is operator-controlled and unconditional. Because the user is not a stakeholder on `TransactionCommitment`, this lets the operator remove active transaction records without a user-side check or notice in the template…
Low acknowledged 6.2.15Statistics Counters Are Not Consistently Monotonic `newTotalTransactions` must be greater than or equal to the current value, but `newTotalVolumeUSD` is only checked for non-negativity and `newUniqueTokens` is not checked against the previous value.
Low fixed 6.2.16Referrer Can Be Rewritten or Removed Without Constraint `SetReferrer` accepts `Optional Party` and only checks that the referrer is not the same as `userParty`. The current code permits unlimited changes and explicit removal via `None`.
Low acknowledged 6.2.17UserStatistics Is Not Derived From Transaction Records `UpdateStatistics` accepts aggregate values and user-preference fields directly. It does not read or reference `TransactionCommitment`, so the statistics record is not mechanically tied to source transactions.
Low fixed 6.2.19ipAddress Is Stored Directly On-Ledger `TermsAcceptance` stores `ipAddress : Optional Text` directly in the contract payload, which means the value becomes part of immutable ledger history once created.
Low fixed 6.2.20Terms Versions Have No On-Ledger Lifecycle Management `termsVersion` is any non-empty string, and there is no registry, deprecation flow, or active-version check. The transaction workflow also does not verify that a user accepted the currently active version.
Low fixed
Methodology
Review process
Scoping and threat modelling
The commit hash is frozen and the attack surface is mapped: asset flows, trust assumptions, privileged roles and the external systems the code depends on.
Automated analysis
Static analysers sweep the full codebase to surface known weakness patterns, unreachable states and deviations from established conventions.
Manual code review
Independent engineers read the code line by line, concentrating on business logic, access control, arithmetic and the handling of external calls.
Adversarial testing
Property-based fuzzing and invariant tests attack the assumptions the protocol relies on, targeting states that ordinary unit tests never reach.
Reporting
Every finding is documented with a severity rating, its impact, the steps to reproduce it and a concrete remediation the team can act on.
Remediation verification
Submitted fixes are re-reviewed against the original finding, and the final report records the resolved state of each one.
Standards and references
- OWASP Top 10The ten most critical web application risks
FAQ
2 separate reviews, the first in March 2026 and the most recent in March 2026. Each one covers its own scope and commit, and is listed individually on this page.
33 findings across all 2 reviews: 4 high, 13 medium and 16 low. 29 of 33 were resolved or mitigated before the final reports.
Each report covers the code as it stood at the commit it names, the most recent in March 2026. Any code changed after that point is outside the reviewed scope.