Back to skill

Security audit

Ponzu Launchpad

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent for Ethereum launchpad work, but it asks users to use wallet-signing authority with unsafe transaction examples and unpinned external package execution that deserve review before installation.

Review this skill carefully before installing or using it with real funds. Use a dedicated low-value wallet, test on Sepolia first, pin and audit npm/MCP package versions, avoid giving a raw private key to an unpinned MCP process, explicitly set and validate your RPC URL, and replace every zero minimum-output transaction example with a quote-based slippage limit before signing.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T08 · Insecure Dependencies

Error
Location
SKILL.md:69
Finding
Unpinned Third-Party Packages Can Execute with Wallet-Signing Access<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:69`, `SKILL.md:88`, and `SKILL.md:711-721` **Vulnerability Type**: Unpinned and automatically executed third-party dependencies **Risk Level**: High ### Vulnerable Code ```bash npm install @ponzu_app/sdk viem ``` ```bash npm install viem ``` ```json { "mcpServers": { "ponzu": { "command": "npx", "args": ["-y", "@ponzu_app/mcp"], "env": { "PONZU_NETWORK": "mainnet" } } } } ``` The documentation subsequently instructs users to grant signing capability: ```text Add PONZU_PRIVATE_KEY for signing capability. ``` ### Technical Analysis The installation commands do not pin package versions or integrity hashes. Consequently, the installed implementation can change between executions without any corresponding change to the reviewed Skill file. The optional MCP configuration is particularly risky because `npx -y` can retrieve and execute the current registry version of `@ponzu_app/mcp` without an interactive installation confirmation. The documentation also directs users to expose `PONZU_PRIVATE_KEY` to this MCP server when transaction signing is required. Package installation and `npx` execution can run package code locally, including package lifecycle scripts and transitive dependencies. If the package publisher, registry account, package contents, or dependency tree is compromised, the retrieved code could access environment variables and perform arbitrary actions with the privileges of the invoking user. ### Attack Path 1. An attacker compromises the publisher account, package release process, or a transitive dependency for `@ponzu_app/sdk`, `@ponzu_app/mcp`, or `viem`. 2. The attacker publishes a malicious version under the expected package name. 3. A user follows the Skill and runs an unpinned `npm install`, or the agent starts the MCP server using `npx -y`. 4. The package manager retrieves and executes the malicious current version. 5. If signing ...[truncated 827 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct package to an exact, reviewed version rather than a floating version. 2. Commit and enforce a package lockfile with integrity metadata. 3. Replace `npx -y @ponzu_app/mcp` with an explicitly installed and version-pinned package, such as a reviewed exact release. 4. Use `npm ci` in controlled environments and reject unexpected lockfile changes. 5. Audit package provenance, signatures, lifecycle scripts, maintainers, and transitive dependencies before granting wallet access. 6. Run the MCP server in a restricted process or container with minimal filesystem and network permissions. 7. Use a dedicated low-value wallet and avoid exposing a raw private key where hardware-wallet or constrained signing mechanisms are available. 8. Add transaction policy controls that restrict destination contracts, chain ID, value, and permitted function selectors. 9. Require explicit human confirmation before signing value transfers, approvals, deployment transactions, or other high-impact operations. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:331
Finding
Transaction Examples Disable Slippage Protection<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:331-337`, `SKILL.md:498-506`, and `SKILL.md:524-531` **Vulnerability Type**: Unsafe minimum-output configuration for blockchain transactions **Risk Level**: High ### Vulnerable Code Presale purchase: ```typescript const ethToSpend = parseEther('0.1') const minTokensOut = 0n // slippage guard: minimum tokens to receive const hash = await wallet.writeContract({ address: presaleAddress, abi: PRESALE_ABI, functionName: 'presale', args: [minTokensOut, ZERO, ZERO], // (minTokenAmount, platformReferrer, orderReferrer) value: ethToSpend, }) ``` ETH-to-token swap: ```typescript const ethIn = parseEther('0.1') const minOut = 0n // set a real value for slippage protection const deadline = BigInt(Math.floor(Date.now() / 1000) + 300) // 5 min await wallet.writeContract({ address: PONZU_ROUTER, abi: ROUTER_ABI, functionName: 'swapExactETHForTokens', args: [minOut, [WETH, tokenAddress], account.address, deadline], value: ethIn, }) ``` Token-to-ETH swap: ```typescript const minEthOut = 0n // set a real value for slippage protection await wallet.writeContract({ address: PONZU_ROUTER, abi: ROUTER_ABI, functionName: 'swapExactTokensForETH', args: [tokenAmountIn, minEthOut, [tokenAddress, WETH], account.address, deadline], }) ``` ### Technical Analysis The examples set the minimum acceptable output to zero for presale and swap operations. Although comments tell users to supply a real value, the executable defaults permit the transaction to succeed regardless of how unfavorable the final output becomes. A minimum-output parameter is the primary on-chain protection against price movement between quotation and execution. Setting it to zero removes this protection. On a public mempool, adversaries can observe pending swaps and place transactions before and after the victim's transaction to manipulate pool reserves. Normal volatility, low liqu ...[truncated 1472 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never provide `0n` as the executable default for minimum output. 2. Query an authoritative on-chain quote immediately before building the transaction. 3. Calculate the minimum output using an explicit bounded tolerance, for example: ```typescript const slippageBps = 50n // 0.5% const minOut = quotedOut * (10_000n - slippageBps) / 10_000n ``` 4. Reject transaction construction when the quote is zero, stale, inconsistent with pool reserves, or when the resulting minimum output is zero. 5. Display the expected output, minimum output, price impact, fees, and slippage tolerance before requesting a signature. 6. Enforce conservative maximum slippage and price-impact limits rather than relying solely on user comments. 7. Recalculate quotes when a transaction has been pending or when pool state changes materially. 8. Consider private transaction submission where appropriate to reduce public-mempool sandwich exposure; this must supplement, not replace, a nonzero minimum output. 9. Add tests that verify all value-bearing purchase and swap examples fail when acceptable output cannot be calculated safely. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:79
Finding
Configured RPC Endpoint Is Ignored by Wallet and Public Client Examples<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:51-57`, `SKILL.md:79-81`, and `SKILL.md:108-110` **Vulnerability Type**: RPC configuration and privacy control mismatch **Risk Level**: Medium ### Vulnerable Code The Skill states that transactions use the configured endpoint: ```text Signed transactions are broadcast to your configured Ethereum RPC endpoint (`PONZU_RPC_URL`). ``` However, the SDK example does not supply that environment variable: ```typescript const account = privateKeyToAccount(process.env.PONZU_PRIVATE_KEY as `0x${string}`) const wallet = createWalletClient({ account, chain: mainnet, transport: http() }) const client = createPublicClient({ chain: mainnet, transport: http() }) ``` The raw viem example has the same behavior: ```typescript const account = privateKeyToAccount(process.env.PONZU_PRIVATE_KEY as `0x${string}`) const wallet = createWalletClient({ account, chain: mainnet, transport: http() }) const publicClient = createPublicClient({ chain: mainnet, transport: http() }) ``` ### Technical Analysis `PONZU_RPC_URL` is declared as a required environment variable, and the security documentation claims that signed transactions are broadcast to that configured endpoint. The implementation examples call `http()` without passing the configured URL. As written, the code may use the RPC URL associated with the selected viem chain configuration rather than the endpoint selected by the user. This creates a security and privacy mismatch: users may believe they are using a trusted, private, authenticated, or self-hosted RPC while requests are sent to a default provider. The examples also hardcode `mainnet` and do not demonstrate validating that the RPC endpoint's chain ID matches the intended `PONZU_NETWORK`. A misconfigured or malicious endpoint could provide misleading state and transaction simulation results, while a network mismatch could cause operational errors. ### Attack Path 1. A user configures `PONZU_RPC_URL` t ...[truncated 1256 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pass the configured endpoint explicitly: ```typescript const rpcUrl = process.env.PONZU_RPC_URL if (!rpcUrl) throw new Error('PONZU_RPC_URL is required') const wallet = createWalletClient({ account, chain: mainnet, transport: http(rpcUrl), }) const publicClient = createPublicClient({ chain: mainnet, transport: http(rpcUrl), }) ``` 2. Derive the viem chain from `PONZU_NETWORK` rather than hardcoding `mainnet`. 3. Query and validate the endpoint's chain ID before reading state or signing a transaction. 4. Stop execution when `PONZU_NETWORK`, the configured viem chain, and the RPC chain ID do not agree. 5. Validate the URL scheme and require HTTPS for remote RPC endpoints, except for explicitly permitted local nodes. 6. Clearly document what information is sent to the RPC operator and avoid claiming that the configured endpoint is used unless the code enforces it. 7. Consider comparing critical reads against a second trusted endpoint before high-value transactions. 8. Add tests confirming that `PONZU_RPC_URL` is consumed and that no implicit default RPC is used. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (3)

External Transmission

Medium
Category
Data Exfiltration
Content
**Option A — IPFS via Pinata (recommended):**
```typescript
// POST image file to https://api.pinata.cloud/pinning/pinFileToIPFS
// POST metadata JSON to https://api.pinata.cloud/pinning/pinJSONToIPFS
// Headers: { Authorization: 'Bearer YOUR_PINATA_JWT' }
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
**Option A — IPFS via Pinata (recommended):**
```typescript
// POST image file to https://api.pinata.cloud/pinning/pinFileToIPFS
// POST metadata JSON to https://api.pinata.cloud/pinning/pinJSONToIPFS
// Headers: { Authorization: 'Bearer YOUR_PINATA_JWT' }
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The swap examples set `amountOutMin`/`minOut` to `0n`, which disables effective slippage protection and can expose users to severe price movement, MEV sandwiching, or unexpectedly poor execution. In a trading/deployment skill that encourages real mainnet interaction, presenting unsafe defaults without a strong inline warning materially increases loss risk.

Static analysis

No suspicious patterns detected.