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
Content-Type: application/json
Authorization: Bearer txs_your_api_key_here
Body
{
"targetContractAddress" : "0x3e391e5cb8ea766c93134faf486e6393158032c2" ,
"chainId" : 1
}
Parameters
Field Type Required Description targetContractAddressstring✅ The contract address to analyze for phishing behavior chainIdnumber✅ Chain to run the check on. See supported IDs below
Supported Chain IDs
Chain chainId Ethereum 1BNB Smart Chain 56Base 8453Arbitrum 42161
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
Field Type Description 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 bytecodeinconclusivebooleantrue if analysis could not complete definitivelyreasonstring | 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
Field Type Description namestringName of the phishing check triggeredbooleanWhether this specific attack vector was detected severitystring"CRITICAL" or "MEDIUM" — the impact level if triggereddetailstringHuman-readable explanation of what was found (or confirmed safe)
Field Type Description 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
Verdict riskScore Range Meaning SAFE0 – 14No phishing behavior detected EMPTY_CONTRACT— No bytecode at this address. Cannot be analyzed INCONCLUSIVE— Analysis 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
Status Error Meaning 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.