Skip to main content

Overview

Most phishing attacks don’t look like phishing — they look like normal contracts. TxShield’s phishing endpoint simulates what a contract actually does when interacted with, not just what it claims to do. Three attack vectors are checked in every scan:
  • Allowance Drain Traps — contracts that call transferFrom to silently sweep your approved ERC20 tokens to an attacker wallet
  • Permit Signature Abuse — contracts that consume a signed permit() to grant unlimited allowance to a malicious address without a second transaction
  • Native ETH Forwarding — contracts that silently forward any ETH you send to an external address instead of doing what they claim

Endpoint

POST /api/phishing/phishing-checks

Request

Headers

Content-Type: application/json Authorization: Bearer txs_your_api_key_here

Body

{
  "targetContractAddress": "0x3e391e5cb8ea766c93134faf486e6393158032c2",
  "chainId": 1
}

Parameters

FieldTypeRequiredDescription
targetContractAddressstringThe contract address to analyze for phishing behavior
chainIdnumberChain to run the check on. See supported IDs below

Supported Chain IDs

ChainchainId
Ethereum1
BNB Smart Chain56
Base8453
Arbitrum42161

Response

{
  "contractAddress": "0x3e391e5cb8ea766c93134faf486e6393158032c2",
  "chain": "ethereum",
  "verdict": "SAFE",
  "riskScore": 0,
  "flagCount": 0,
  "isEmpty": false,
  "inconclusive": false,
  "reason": null,
  "checks": [
    {
      "name": "Allowance Drain Trap",
      "triggered": false,
      "severity": "CRITICAL",
      "detail": "Target did not attempt to drain approved ERC20 allowances."
    },
    {
      "name": "Permit Signature Abuse",
      "triggered": false,
      "severity": "CRITICAL",
      "detail": "Target did not attempt to consume permit signatures."
    },
    {
      "name": "Native ETH Forwarder",
      "triggered": false,
      "severity": "MEDIUM",
      "detail": "Target retained ETH — no silent forwarding detected."
    }
  ],
  "raw": {
    "allowanceDrained": false,
    "drainedTo": null,
    "drainedAmount": null,
    "permitAbused": false,
    "permitGrantedTo": null,
    "etherForwarded": false,
    "etherForwardedTo": null
  },
  "detectedAt": "2025-01-01T00:00:00.000Z"
}

Response Fields Explained

Top Level

FieldTypeDescription
contractAddressstringThe contract address that was analyzed
chainstringThe chain the analysis ran on
verdictstringHuman-readable risk verdict. See verdict table below
riskScorenumberComposite risk score from 0 to 100
flagCountnumberNumber of phishing checks that triggered
isEmptybooleantrue if the address has no deployed bytecode
inconclusivebooleantrue if analysis could not complete definitively
reasonstring | nullPopulated when isEmpty or inconclusive is true, explaining why
checksarrayResults of each individual phishing check
rawobjectRaw extracted values for direct frontend consumption
detectedAtstringISO 8601 timestamp of when the analysis ran

checks[] — Each Phishing Check

FieldTypeDescription
namestringName of the phishing check
triggeredbooleanWhether this specific attack vector was detected
severitystring"CRITICAL" or "MEDIUM" — the impact level if triggered
detailstringHuman-readable explanation of what was found (or confirmed safe)

raw — Extracted Attack Data

FieldTypeDescription
allowanceDrainedbooleanWhether a transferFrom drain was detected
drainedTostring | nullAttacker address that received the drained tokens
drainedAmountstring | nullAmount of tokens routed to the attacker
permitAbusedbooleanWhether a permit() signature was consumed maliciously
permitGrantedTostring | nullAddress that received the permit-granted allowance
etherForwardedbooleanWhether received ETH was silently forwarded out
etherForwardedTostring | nullAddress ETH was forwarded to. null if chain tracing is unavailable

Verdict Reference

VerdictriskScore RangeMeaning
SAFE0 – 14No phishing behavior detected
EMPTY_CONTRACTNo bytecode at this address. Cannot be analyzed
INCONCLUSIVEAnalysis ran but could not reach a definitive verdict
LOW_RISK15 – 39Minor flags detected. Proceed with caution
HIGH_RISK40 – 74Active phishing indicators found. Warn the user strongly
CRITICAL75 – 100Confirmed phishing attack vector. Block the transaction
isEmpty and inconclusive override riskScore in the verdict. Always check these flags first. An empty contract address is a common front for phishing flows where the real attack happens one hop away.

How to Read the Results

The Safe Contract

{
  "verdict": "SAFE",
  "riskScore": 0,
  "flagCount": 0,
  "checks": [
    { "name": "Allowance Drain Trap",   "triggered": false },
    { "name": "Permit Signature Abuse", "triggered": false },
    { "name": "Native ETH Forwarder",  "triggered": false }
  ]
}
All three checks clean. No flags. Safe to proceed.

The Allowance Drain Trap

{
  "verdict": "CRITICAL",
  "riskScore": 95,
  "flagCount": 1,
  "checks": [
    {
      "name": "Allowance Drain Trap",
      "triggered": true,
      "severity": "CRITICAL",
      "detail": "Target called transferFrom and routed 50000000000 tokens to 0xDead...Beef"
    },
    { "name": "Permit Signature Abuse", "triggered": false },
    { "name": "Native ETH Forwarder",  "triggered": false }
  ],
  "raw": {
    "allowanceDrained": true,
    "drainedTo": "0xDeadBeef...",
    "drainedAmount": "50000000000"
  }
}
The contract calls transferFrom and routes your approved tokens to an attacker wallet. Classic approval phishing. Block immediately.

The Permit Signature Abuser

{
  "verdict": "CRITICAL",
  "riskScore": 90,
  "flagCount": 1,
  "checks": [
    { "name": "Allowance Drain Trap", "triggered": false },
    {
      "name": "Permit Signature Abuse",
      "triggered": true,
      "severity": "CRITICAL",
      "detail": "Target called permit() and granted allowance to 0xDead...Beef"
    },
    { "name": "Native ETH Forwarder", "triggered": false }
  ],
  "raw": {
    "permitAbused": true,
    "permitGrantedTo": "0xDeadBeef..."
  }
}
The contract consumes a permit() signature to grant itself or a third party unlimited token allowance — without ever asking for a second approval transaction. The user thinks they’re signing a gasless swap. They’re handing over their wallet.

The Silent ETH Forwarder

{
  "verdict": "HIGH_RISK",
  "riskScore": 60,
  "flagCount": 1,
  "checks": [
    { "name": "Allowance Drain Trap",   "triggered": false },
    { "name": "Permit Signature Abuse", "triggered": false },
    {
      "name": "Native ETH Forwarder",
      "triggered": true,
      "severity": "MEDIUM",
      "detail": "Target forwarded received ETH to 0xDead...Beef"
    }
  ],
  "raw": {
    "etherForwarded": true,
    "etherForwardedTo": "0xDeadBeef..."
  }
}
Any ETH sent to this contract is silently routed to an external address. Common in fake mint pages and impersonation contracts where the UI looks legitimate but funds never stay in the contract.

The Empty Contract

{
  "verdict": "EMPTY_CONTRACT",
  "riskScore": 0,
  "isEmpty": true,
  "reason": "No bytecode found at this address on this chain",
  "checks": []
}
Nothing is deployed here. This may be a pre-deployment address used in a phishing link, a wrong chain, or a destroyed contract. Do not interact with it.

Code Examples

curl -X POST https://api.txshield.xyz/api/phishing/phishing-checks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer txs_your_api_key_here" \
  -d '{
    "targetContractAddress": "0x3e391e5cb8ea766c93134faf486e6393158032c2",
    "chainId": 1
  }'

Error Responses

StatusErrorMeaning
400targetContractAddress is requiredMissing address in body
400chainId is requiredMissing chainId in body
401Missing Authorization headerNo API key provided
403Invalid API keyKey not found or revoked
429Analysis rate limit hitExceeded 10 req/min
500Phishing check failedInternal error or RPC failure

EVM Honeypot Detection

Detect time-delayed tax traps and blacklists alongside phishing checks.

Authentication

How to generate and use your API key.