Aman Sriven
Back to the portfolio

Undergraduate research · 2025

Smart Contract Residual Attention NetSCRAN

A deep-learning model that flags eleven kinds of security vulnerability in Solidity smart contracts, scoring 0.87 macro F1 against 0.75 for the previously published model on the same dataset.

Period
December 2024 — May 2025
My role
First author; trained the PyTorch ensemble
Built with
PyTorch · multi-head attention · focal loss · SMOTE
  • 0.87macro F1vs 0.75 for the previous model on the same data
  • 95%of vulnerabilities caughtaverage across the eleven classes
  • 0.997macro AUChow well it ranks risky contracts first

In brief

Smart contracts · Vulnerability detection · Deep learning

SCRAN reads a Solidity smart contract, reduced to 240 static features, and flags which of eleven vulnerability classes it contains. A contract can carry several at once, so each class gets its own independent answer.

The hard part is imbalance: some classes appear in under one percent of the 111,897 contracts in BCCC-SCsVul-2024. Focal loss, oversampling, and per-class thresholds do most of the work, and a three-model ensemble steadies the result. On a held-out test split that never saw resampling or threshold tuning, it reaches a macro F1 of 0.8703 and a macro AUC of 0.9973.

The domain is smart contracts; the skills are general. Learning from badly imbalanced data, choosing metrics that don't flatter the model, and reporting the trade-offs rather than hiding them carry over to any problem where rare events are the ones that matter.

Results

Held-out test split · 20% of the corpus

Table ITest-set performance across twelve classes. The test split is untouched by oversampling, augmentation, or threshold tuning.
Precision, recall, F1 score, and AUC for each vulnerability class.
VulnerabilityPrecision to recall spanPrecisionRecallF1AUC
SecureNonVulnerable0.97750.99680.98710.9998
Integer under/overflowIntegerUO0.95630.99260.97410.9996
Denial of serviceDenialOfService0.96210.98570.97370.9995
Call to unknownCallToUnknown0.95090.98650.96840.9995
Re-entrancyReentrancy0.95670.97990.96810.9994
Weak access modifierWeakAccessMod0.87360.98960.92800.9999
Gas exceptionGasException0.75980.94250.84140.9954
External bugExternalBug0.73060.92540.81660.9967
Mishandled exceptionMishandledException0.70060.92770.79830.9940
Unused returnUnusedReturn0.64970.95190.77230.9969
Transaction order dependenceTOD0.62130.91610.74040.9942
Timestamp dependenceTimestamp0.54340.89140.67520.9924
Macro average12 classes0.80690.95720.87030.9973

The shape of that chart is the finding. Recall never drops below 0.89, so the model rarely misses a vulnerability that is present. Precision is what varies, and every long span is a class the model over-reports. Timestamp dependence is the worst at 0.5434 precision: close to one wrong flag for every right one.

AUC stays above 0.99 everywhere, including those weak classes. The ranking is good even where the decision is not, so the failure is in where the threshold lands rather than in what the network learned.

Against EGA profiling (HajiHosseinKhani et al., 2024), the previously published model on this same dataset, SCRAN raises macro F1 from 0.75 to 0.87 and has the higher F1 on every one of the twelve classes. EGA profiling keeps the edge on macro precision (0.86 against 0.81), and it was built to be explainable, which SCRAN is not.

One trade is worth stating: a single model scores a slightly higher macro F1 (0.8762) than the ensemble (0.8703). The ensemble was kept for its higher AUC and steadier behaviour on the rare classes.

Architecture

Residual · Attention · Class-specific heads

A contract arrives as 240 numbers. The question is which of eleven failure modes those numbers imply — and a contract can be guilty of several at once, so the eleven answers have to be independent rather than a single choice among classes.

Figure 1SCRAN forward pass — 240 static features in, 11 independent vulnerability probabilities out.
  1. 01

    Static features

    x ∈ ℝ²⁴⁰

  2. 02

    Residual FC ×2

    LayerNorm · ReLU · Dropout

  3. 03

    Multi-head attention

    softmax(QKᵀ/√d)·V

  4. 04

    Class-specific heads

    αⱼ = softmax(aⱼ)

  5. 05

    Per-class sigmoid

    ŷ ∈ [0,1]¹¹

Ensemble

  • γ = 2.0
  • γ = 2.5
  • γ = 3.0

Three instances of the network above, each trained under a different focal focusing parameter and learning rate. Their logits are combined with per-class weights taken from validation F1, so a model that is good at re-entrancy and bad at timestamps is trusted accordingly.

  1. 01Static features. Control-flow analysis and opcode statistics, z-score normalised per feature.
  2. 02Residual FC ×2. Two fully connected blocks with skip connections, projected when the dimensions do not line up.
  3. 03Multi-head attention. Positional encoding, scaled dot-product attention, then a residual LayerNorm and a GELU feed-forward block.
  4. 04Class-specific heads. Eleven attention heads, one per vulnerability, each weighting the feature dimensions independently.
  5. 05Per-class sigmoid. Thresholds are chosen per class off the precision–recall curve rather than left at 0.5.

Limits

And what I would do next

The model never sees a contract, only 240 numbers extracted from one. That is why the classes it struggles with are the ones defined by execution context rather than structure. Dynamic traces or a graph encoder over the control-flow graph would give it what it is missing, and that is the first change I would make.

Every number here comes from one corpus, and SCRAN trades away some explainability: its attention heads say which features mattered, which is not a reason an auditor can act on. The paper covers both, along with the comparisons against prior work.

The paper

7 pages · PDF

Acknowledgements

Written with Dr. Irfan Khan, who advised the work, and with help from graduate students Zahid Hussain and Shorya Agarwal.

Read the paper