Skip to main content
Glama

contract_analyze

Analyze Hedera smart contracts to assess risks, examine activity patterns, evaluate gas usage, and classify contract functionality for security and performance insights.

Instructions

Deep analysis of a Hedera smart contract including activity patterns, caller distribution, gas usage, risk assessment, and functional classification. Costs 1 HBAR.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
api_keyYesYour HederaIntel API key
contract_idYesHedera contract ID to analyze (e.g. 0.0.123456)

Implementation Reference

  • The handler function for the `contract_analyze` tool, which fetches contract data, analyzes activities, gas usage, success rates, and performs a risk assessment.
    // --- contract_analyze ---
    if (name === "contract_analyze") {
      const payment = chargeForTool("contract_analyze", args.api_key);
      const base = getMirrorNodeBase();
    
      // Fetch contract info
      const contractRes = await axios.get(`${base}/api/v1/contracts/${args.contract_id}`);
      const contract = contractRes.data;
    
      // Fetch recent results (up to 100)
      const resultsRes = await axios.get(
        `${base}/api/v1/contracts/${args.contract_id}/results?limit=100&order=desc`
      ).catch(() => ({ data: { results: [] } }));
      const results = resultsRes.data.results || [];
    
      // Fetch contract logs
      const logsRes = await axios.get(
        `${base}/api/v1/contracts/${args.contract_id}/results/logs?limit=50&order=desc`
      ).catch(() => ({ data: { logs: [] } }));
      const logs = logsRes.data.logs || [];
    
      // Fetch state
      const stateRes = await axios.get(
        `${base}/api/v1/contracts/${args.contract_id}/state?limit=25`
      ).catch(() => ({ data: { state: [] } }));
      const stateEntries = stateRes.data.state || [];
    
      // Contract age
      const createdAt = contract.created_timestamp
        ? new Date(parseFloat(contract.created_timestamp) * 1000)
        : null;
      const ageDays = createdAt
        ? Math.floor((Date.now() - createdAt.getTime()) / (1000 * 60 * 60 * 24))
        : null;
    
      // Caller analysis
      const callerCounts = {};
      for (const r of results) {
        if (r.from) callerCounts[r.from] = (callerCounts[r.from] || 0) + 1;
      }
      const topCallers = Object.entries(callerCounts)
        .sort((a, b) => b[1] - a[1])
        .slice(0, 5)
        .map(([account, count]) => ({ account, call_count: count }));
    
      // Gas analysis
      const gasUsed = results.map(r => parseInt(r.gas_used || 0)).filter(g => g > 0);
      const avgGas = gasUsed.length > 0
        ? Math.round(gasUsed.reduce((a, b) => a + b, 0) / gasUsed.length)
        : 0;
      const maxGas = gasUsed.length > 0 ? Math.max(...gasUsed) : 0;
      const minGas = gasUsed.length > 0 ? Math.min(...gasUsed) : 0;
    
      // Success/failure rate
      // Mirror node contract results: status field is "0x1" (success) or "0x0" (fail)
      // result field may contain revert reason strings for failures
      const successCount = results.filter(r =>
        r.status === "0x1" || r.result === "SUCCESS" || (!r.status && !r.error_message)
      ).length;
      const failCount = results.filter(r =>
        r.status === "0x0" || (r.error_message && r.error_message.length > 0)
      ).length;
    
      // Activity trend - group by day
      const dayActivity = {};
      for (const r of results) {
        if (r.timestamp) {
          const day = new Date(parseFloat(r.timestamp) * 1000).toISOString().slice(0, 10);
          dayActivity[day] = (dayActivity[day] || 0) + 1;
        }
      }
      const activityByDay = Object.entries(dayActivity)
        .sort((a, b) => b[0].localeCompare(a[0]))
        .slice(0, 7)
        .map(([date, count]) => ({ date, calls: count }));
    
      // Function signature analysis from call data
      const functionCalls = {};
      for (const r of results) {
        if (r.function_parameters && r.function_parameters.length >= 10) {
          const sig = r.function_parameters.slice(0, 10);
          functionCalls[sig] = (functionCalls[sig] || 0) + 1;
        }
      }
      const topFunctions = Object.entries(functionCalls)
        .sort((a, b) => b[1] - a[1])
        .slice(0, 5)
        .map(([selector, count]) => ({ selector, call_count: count }));
    
      // Risk assessment
      const riskSignals = [];
      let riskScore = 0;
    
      if (!contract.admin_key) { riskSignals.push("No admin key - contract is immutable (good for decentralization)"); }
      if (contract.deleted) { riskScore += 50; riskSignals.push("Contract has been DELETED"); }
      if (failCount > 0 && failCount > successCount && results.length > 5) { riskScore += 20; riskSignals.push("High failure rate - more failed calls than successful ones"); }
      if (ageDays !== null && ageDays < 7) { riskScore += 15; riskSignals.push("Very new contract - deployed less than 7 days ago"); }
      if (topCallers.length === 1 && results.length > 10) { riskScore += 10; riskSignals.push("Single caller dominates all interactions"); }
      if (stateEntries.length === 0 && results.length > 0) { riskSignals.push("No readable state entries - contract may use non-standard storage"); }
      if (riskSignals.length === 0) riskSignals.push("No significant risk signals detected");
    
      const riskLevel = riskScore >= 40 ? "HIGH" : riskScore >= 15 ? "MEDIUM" : "LOW";
    
      // Contract classification guess
      let classification = "Unknown";
      const logTopics = logs.map(l => (l.topics || [])[0]).filter(Boolean);
      const uniqueTopics = [...new Set(logTopics)];
      if (uniqueTopics.some(t => t.startsWith("0xddf252ad"))) classification = "ERC20 / HTS Token";
      else if (uniqueTopics.some(t => t.startsWith("0xc3d58168"))) classification = "ERC1155 Multi-Token";
      else if (uniqueTopics.some(t => t.startsWith("0x17307eab"))) classification = "ERC721 NFT";
      else if (results.length > 50) classification = "High-activity contract (DEX, lending, or staking likely)";
      else if (results.length > 0) classification = "General purpose smart contract";
    
      return {
        contract_id: args.contract_id,
        evm_address: contract.evm_address || null,
        created_at: createdAt ? createdAt.toISOString() : null,
        age_days: ageDays,
        deleted: contract.deleted || false,
        hbar_balance: contract.balance?.balance
          ? (contract.balance.balance / 100000000).toFixed(4) + " HBAR"
          : "0.0000 HBAR",
        classification,
        activity: {
          total_calls_sampled: results.length,
          successful_calls: successCount,
          failed_calls: failCount,
          success_rate: results.length > 0 ? ((successCount / results.length) * 100).toFixed(1) + "%" : "unknown",
          unique_callers: Object.keys(callerCounts).length,
          recent_logs: logs.length,
          state_entries: stateEntries.length,
        },
        gas_analysis: {
          avg_gas_used: avgGas,
          max_gas_used: maxGas,
          min_gas_used: minGas,
        },
        top_callers: topCallers,
        top_function_selectors: topFunctions,
        activity_last_7_days: activityByDay,
        risk_assessment: {
          score: riskScore,
          level: riskLevel,
          signals: riskSignals,
        },
        payment,
        timestamp: new Date().toISOString(),
      };
    }
  • The definition and input schema for the `contract_analyze` tool.
    {
      name: "contract_analyze",
      description: "Deep analysis of a Hedera smart contract including activity patterns, caller distribution, gas usage, risk assessment, and functional classification. Costs 1.5 HBAR.",
      inputSchema: {
        type: "object",
        properties: {
          contract_id: { type: "string", description: "Hedera contract ID to analyze (e.g. 0.0.123456)" },
          api_key: { type: "string", description: "Your HederaIntel API key" },
        },
        required: ["contract_id", "api_key"],
      },
    },
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden and discloses key behavioral traits: it's a paid operation ('Costs 1 HBAR'), involves computational analysis ('Deep analysis'), and outlines specific analytical aspects. However, it doesn't mention rate limits, error conditions, or output format details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with core purpose, followed by specific analysis components and cost, all in two efficient sentences with zero wasted words. Every element adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter tool with no annotations and no output schema, the description covers purpose and cost well but lacks details on output structure, error handling, or performance characteristics. It's adequate but has clear gaps given the analytical complexity implied.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so parameters are fully documented in the schema. The description adds no additional parameter semantics beyond implying contract_id is for analysis, aligning with the baseline expectation when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Deep analysis') and resource ('Hedera smart contract'), with detailed scope ('activity patterns, caller distribution, gas usage, risk assessment, and functional classification'). It distinguishes from siblings like contract_call (execution) or contract_read (simple query) by emphasizing comprehensive analysis.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for in-depth contract analysis but lacks explicit guidance on when to choose this over alternatives like token_analyze or governance_analyze. It mentions cost ('Costs 1 HBAR'), which provides some context but doesn't specify prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/mountainmystic/hederatoolbox'

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