career·9 min का पठन·Solingo द्वारा

Smart Contract Audit Contests कैसे जीतें

Code4rena और Sherlock जैसे contests के लिए एक practical, दोहराने योग्य workflow: तेज़ी से scoping, high-severity bugs की खोज, वे bug classes जो वाकई score करती हैं, और ऐसे reports लिखना जिन्हें judges reward करते हैं।

# Smart Contract Audit Contests कैसे जीतें

Public audit contests security में सबसे तेज़ और सबसे कठोर feedback loop देते हैं। आप वही codebase पढ़ते हैं जिसे पूरी दुनिया भी पढ़ रही है, आपके पास कुछ ही दिन होते हैं, और पैसा सिर्फ़ unique, valid और high-severity findings पर मिलता है। यह guide एक ऐसा workflow देती है जो बिखरी हुई मेहनत को लगातार अच्छे placements में बदलता है, आपके पहले contest से लेकर पहली leaderboard finish तक।

शुरू करने से पहले अपनी expectations तय करें

ज़्यादातर नए लोग एक या दो contests के बाद छोड़ देते हैं क्योंकि उन्होंने तुरंत पैसे जीतने की उम्मीद की थी। reward distribution बहुत asymmetric होती है: एक अकेला High दस Lows से भारी पड़ता है, और duplicates pot को बाँट देते हैं। पहले दस contests में आपका असली लक्ष्य calibration है: यह सीखना कि कौन से findings valid हैं, कौन से noise हैं, और judges severity को कैसे तौलते हैं। शुरुआती contests को paid practice मानें।

ज़्यादातर contest frameworks में severity, impact गुणा likelihood का एक function होती है:

  • High: funds का सीधा नुकसान या lock हो जाना, या साफ़ तौर पर protocol तोड़ने वाला state, एक plausible path के साथ।
  • Medium: नुकसान सिर्फ़ specific conditions में, या core functionality टूटना बिना सीधे चोरी के।
  • Low / Informational: code quality, funds या logic पर कोई असली impact नहीं। यह शायद ही कभी pay करता है।

अगर कोई bug "और इसलिए funds खो जाते हैं, फँस जाते हैं या चोरी हो जाते हैं" पर खत्म नहीं हो सकता, तो वह शायद High नहीं है।

Phase 1: तेज़ी से scope करें (पहले दो घंटे)

सबसे बड़ी file की पहली line से शुरू मत कीजिए। पहले एक map बनाइए।

  • README और docs पढ़ें। protocol आपको बताता है कि उसे क्या करना चाहिए। bugs इरादे और असली behavior के बीच की gap में रहते हैं।
  • scope में lines गिनें। cloc या solidity-metrics जैसे tools दिखाते हैं कि complexity कहाँ है।
  • actors और money paths की list बनाएँ। कौन deposit करता है, कौन withdraw करता है, कौन privileged है, कौन liquidate हो सकता है। funds इन्हीं edges पर चलते हैं, और bugs भी।
  • जाने-पहचाने forks से diff करें। कई protocols Uniswap, Compound या किसी OpenZeppelin base को fork करते हैं। original से तुलना करने पर custom changes सामने आते हैं, और auditable risk ठीक वहीं रहता है।
  • # तेज़ complexity map
    

    cloc src/ --by-file

    # external और public functions गिनें, यानी attack surface

    grep -rEn 'function .*\b(external|public)\b' src/ | wc -l

    phase one के अंत तक आपको दो वाक्यों में बता पाना चाहिए कि protocol कैसे पैसा कमाता और घुमाता है। अगर नहीं बता पाते, तो mapping जारी रखें।

    Phase 2: high-severity bugs की खोज करें

    Generality, line-by-line पढ़ने से बेहतर है। codebase को बार-बार आने वाली bug classes के lens से देखें, क्योंकि एक ही गलतियाँ अलग-अलग protocols में दोहराई जाती हैं।

    वे bug classes जो score करती हैं

    • Accounting और rounding. multiplication से पहले division, गलत दिशा में round होने वाली fee math, vaults में share-price manipulation (ERC-4626 पर classic first-depositor inflation attack)।
    • Access control gaps. किसी privileged function पर modifier न होना, दो बार call हो सकने वाला initializer, गलत address की तुलना करने वाला role check।
    • Reentrancy, जिसमें read-only reentrancy भी शामिल है। callback के बीच में state पढ़ना उसके update होने से पहले। cross-function और cross-contract variants में ही असली पैसा होता है, textbook वाला single-function case नहीं।
    • Oracle और price manipulation. एक ही AMM pool से spot price, कोई TWAP नहीं, price feed पर कोई staleness check नहीं।
    • Unchecked external calls और return values. ऐसा token जो revert करने के बजाय false लौटाता है, ऐसा low-level call जिसका success flag ignore कर दिया जाता है।
    • Slippage और deadline. बिना minimum-out या hardcoded zero वाले swaps, जो users को sandwiching के लिए खुला छोड़ देते हैं।

    इस realistic vault pattern को देखें। bug subtle और high-severity है:

    // SPDX-License-Identifier: MIT
    

    pragma solidity ^0.8.20;

    contract Vault {

    mapping(address => uint256) public shares;

    uint256 public totalShares;

    IERC20 public immutable asset;

    constructor(IERC20 _asset) {

    asset = _asset;

    }

    function deposit(uint256 amount) external returns (uint256 minted) {

    uint256 totalAssets = asset.balanceOf(address(this));

    // जब totalShares == 0 हो, shares 1:1 mint होते हैं

    minted = totalShares == 0

    ? amount

    : (amount * totalShares) / totalAssets;

    shares[msg.sender] += minted;

    totalShares += minted;

    asset.transferFrom(msg.sender, address(this), amount);

    }

    }

    finding: एक attacker 1 wei deposit करता है, 1 share पाता है, फिर asset की बड़ी मात्रा सीधे vault को transfer कर देता है। अब totalAssets बहुत बड़ा है जबकि totalShares सिर्फ़ 1 है। अगला ईमानदार depositor minted = (amount * 1) / totalAssets निकालता है, जो एक असली deposit के लिए round down होकर zero shares बन जाता है, और उसके funds attacker को दान कर देता है। fix यह है कि construction पर dead shares mint करें, या balanceOf पढ़ने के बजाय totalAssets को internally track करें।

    इन्हें असल में कैसे खोजें

    • हर external function के लिए पूछें: अगर मैं इसे zero के साथ, max uint के साथ, एक ही transaction में दो बार, या तय order से बाहर call करूँ तो क्या होगा?
    • हर transfer और call को follow करें। पक्का करें कि return value check हो रहा है और external call से पहले state update हो रहा है।
    • एक property लिखें और उसे fuzzer से तोड़ने की कोशिश करें। accounting bugs के लिए Foundry के invariant tests बहुत अच्छे हैं:
    function invariant_totalSharesBackedByAssets() public view {
    

    // कुल redeemable value कभी रखे हुए assets से ज़्यादा नहीं होनी चाहिए

    assertLe(vault.totalShares(), asset.balanceOf(address(vault)) + 1);

    }

    एक pass होता हुआ proof-of-concept test "शायद" को High में बदल देता है। judges उन findings को reward करते हैं जिन्हें वे चला सकें।

    Phase 3: ऐसे reports लिखें जिन्हें judges reward करें

    सही bug भी कमज़ोर writeup के साथ downgrade हो जाता है या किसी बेहतर लिखे finding का duplicate मार दिया जाता है। हर finding को एक ही तरह structure करें:

  • Title: severity के साथ एक-line impact, जैसे "High: first depositor share inflation के ज़रिए बाद के deposits चुरा सकता है"।
  • Summary: दो-तीन वाक्य जो एक व्यस्त judge तुरंत समझ ले।
  • Impact: क्या खोता, फँसता या चोरी होता है, और किन conditions में।
  • Proof of concept: एक चलने योग्य test या एक सटीक numeric walkthrough। यही सबसे बड़ा differentiator है।
  • Recommended mitigation: ठोस fix, आदर्श रूप से एक diff।
  • एक थके हुए reader के लिए लिखें। impact पहली line में बताएँ, उसे कभी मत दबाएँ। speculation से बचें: अगर आप नुकसान दिखा नहीं सकते, तो ईमानदारी से कहें और खुद को downgrade करें, बजाय इसके कि "invalid" mark का जोखिम लें जो आपके accuracy score को नुकसान पहुँचाता है।

    पूरे contest window में time management

    एक हफ़्ते का contest एक marathon है जिसके अंत में एक sprint होता है।

    • Day 1: सिर्फ़ scope और mapping। अभी कोई finding नहीं।
    • Days 2 से 4: money paths के साथ गहरी dives, एक बार में एक subsystem। हर शक एक scratch file में लिखें, चाहे आधा-अधूरा ही क्यों न हो।
    • Day 5: अपनी सबसे मज़बूत leads के लिए proof-of-concept tests बनाएँ। कमज़ोर leads छोड़ दें।
    • Final day: writeups को polish करें, severities दोबारा check करें, submit करें। आख़िरी घंटों में किसी नई lead के पीछे मत भागें; जो साबित कर सकते हैं उसे पूरा करें।

    अपना ध्यान बचाकर रखें। एक subsystem पर दो घंटे की focused review, सब कुछ सरसरी तौर पर देखने के पूरे दिन से बेहतर है।

    beginner से आगे बढ़ना

    • judged reports पढ़ें। हर contest के बाद उन Highs का अध्ययन करें जो place हुए। आपको वही patterns दोबारा दिखेंगे।
    • एक personal bug-class checklist रखें और हर contract को उसमें से गुज़ारें। आपकी बढ़त pattern recognition है, और checklist इसे systematic बनाती है।
    • Specialize करें। एक niche चुनें (vaults, lending, bridges, AMMs) और गहराई में जाएँ। specialists अपने domain में generalists से ज़्यादा findings निकालते हैं।
    • proof-of-concept की muscle बनाएँ। Foundry tests लिखने की speed सीधे तौर पर यह multiply करती है कि deadline से पहले आप कितने findings confirm कर सकते हैं।

    इसे hands-on practice करें

    इन bug classes को आत्मसात करने का सबसे तेज़ तरीका है उन्हें एक सुरक्षित environment में जानबूझकर exploit करना, फिर उन्हें fix करना। app.solingo-blockchain.xyz पर आप audit-style exercises कर सकते हैं, proof-of-concept exploits लिख सकते हैं, और अपने severity reasoning को worked solutions से मिलाकर देख सकते हैं। accounting और access-control tracks से शुरू करें, फिर reentrancy और oracle manipulation पर जाएँ। code पढ़ें, उसे तोड़ें, report लिखें, दोहराएँ।

    Practice में लगाने के लिए तैयार हैं?

    Solingo पर interactive exercises के साथ इन concepts को apply करें।

    मुफ्त में शुरू करें