Skip to main content
Glama
lordbasilaiassistant-sudo

base-security-scanner-mcp

scan_contract

Analyze smart contracts on Base mainnet to detect security vulnerabilities including reentrancy patterns, access control issues, hidden mints, proxy patterns, and dangerous opcodes.

Instructions

Analyze a smart contract on Base mainnet for security issues including reentrancy patterns, access control, hidden mints, proxy patterns, and dangerous opcodes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
addressYesContract address on Base mainnet

Implementation Reference

  • The handler implementation for the "scan_contract" tool. It fetches bytecode, extracts function selectors, analyzes opcodes, identifies contract types, checks ownership, and performs various security checks based on the extracted information.
    server.tool(
      "scan_contract",
      "Analyze a smart contract on Base mainnet for security issues including reentrancy patterns, access control, hidden mints, proxy patterns, and dangerous opcodes.",
      {
        address: z.string().describe("Contract address on Base mainnet"),
      },
      async ({ address }) => {
        try {
          const code = await getContractBytecode(address);
          if (code === "0x" || code.length <= 2) {
            return ok({ address, isContract: false, message: "Address is not a contract (EOA or empty)" });
          }
    
          const selectors = extractSelectors(code);
          const { findings, riskCounts } = analyzeSelectorRisks(selectors);
          const opcodes = analyzeOpcodes(code);
          const contractTypes = identifyContractType(selectors);
          const ownership = await checkOwnership(address);
    
          const issues: Array<{ severity: string; issue: string; detail: string }> = [];
    
          // Reentrancy risk: delegatecall + external calls
          if (opcodes.hasDelegatecall) {
            issues.push({ severity: "high", issue: "DELEGATECALL present", detail: "Contract uses delegatecall which can execute arbitrary external code. Potential reentrancy or logic manipulation risk." });
          }
    
          // Selfdestruct
          if (opcodes.hasSelfDestruct) {
            issues.push({ severity: "critical", issue: "SELFDESTRUCT present", detail: "Contract can be destroyed. All funds and state will be lost permanently." });
          }
    
          // Access control issues
          if (ownership.hasOwner && !ownership.isRenounced) {
            const dangerousWithOwner = findings.filter(f => f.risk === "critical" || f.risk === "high");
            if (dangerousWithOwner.length > 0) {
              issues.push({
                severity: "high",
                issue: "Active owner with dangerous permissions",
                detail: `Owner (${ownership.owner}) can call: ${dangerousWithOwner.map(f => f.name).join(", ")}`,
              });
            }
          }
    
          // Hidden mint
          const hasMint = findings.some(f => f.selector === "40c10f19");
          if (hasMint) {
            issues.push({ severity: "critical", issue: "Mint function detected", detail: "Owner can mint unlimited tokens, diluting holders." });
          }
    
          // Proxy patterns
          const isProxy = contractTypes.includes("Proxy Contract");
          if (isProxy) {
            issues.push({ severity: "medium", issue: "Proxy contract", detail: "Contract logic can be upgraded. The code you see today may change tomorrow." });
          }
    
          // Token approval traps: check if there's approve but unusual patterns
          const hasApprove = findings.some(f => f.selector === "095ea7b3");
          const hasTransferFrom = findings.some(f => f.selector === "23b872dd");
          if (hasApprove && !hasTransferFrom) {
            issues.push({ severity: "medium", issue: "Approve without transferFrom", detail: "Contract has approve() but no transferFrom(). Unusual pattern — may trap approvals." });
          }
    
          // Trading control
          const hasTradingControl = findings.some(f => f.selector === "1a8145bb");
          if (hasTradingControl) {
            issues.push({ severity: "critical", issue: "Trading can be disabled", detail: "Owner can call setTradingActive(false) to prevent all trading." });
          }
    
          return ok({
            address,
            contractTypes,
            bytecodeSize: (code.length - 2) / 2,
            ownership: serializeBigInts(ownership) as Record<string, unknown>,
            opcodeAnalysis: opcodes,
            riskCounts,
            issues,
            knownFunctions: findings,
            totalSelectorsFound: selectors.length,
          });
        } catch (err) {
          return fail(`scan_contract failed: ${err instanceof Error ? err.message : String(err)}`);
        }
      }
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lordbasilaiassistant-sudo/base-security-scanner-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server