> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tenderly.co/llms.txt
> Use this file to discover all available pages before exploring further.

# एक Hack की जाँच (Cover Protocol)

> Tenderly में Cover Protocol exploit का विश्लेषण करें, contract को import करके, deposit को simulate करके, और Debugger में cache bug को trace करके।

यह उदाहरण संक्षेप में यह दिखाएगा कि Tenderly का उपयोग हैक्स का विश्लेषण करने और यहाँ तक कि रोकने के लिए कैसे किया जा सकता है, जैसा कि [Cover Protocol](https://twitter.com/CoverProtocol) के साथ हुआ था।

Cover Protocol हैक हो गया क्योंकि code storage में cache को अपडेट करने में असमर्थ था। इसे deposit/withdrawal और विशेष state changes जैसे महत्वपूर्ण functions पर [**अलर्ट सेट करके**](/monitoring/alerts/introduction) संभावित रूप से रोका जा सकता था ताकि हमले को रोका जा सके।

Hack का manually विश्लेषण करने के लिए, हमें उस smart contract `Blacksmith` को [**import**](/developer-explorer/contracts) करना होगा जिसमें भेद्यता पाई गई थी। यदि आप प्रभावित protocol या vulnerable contract का सटीक नाम जानते हैं तो आप उसे सीधे search भी कर सकते हैं।

![](https://lh3.googleusercontent.com/BVJobjB-JHrSGyTHuC7v3cPLBbaUnNJH3pda8uJrHU2qCSV6ms-84BC614vdozpemjg5FO8J4cu-B9RjTTLfYWRQyBneYVBbLy5fv5_OQA1N-svrza9ZF6Q6xsUA5o37YyYPnaP4)

<Warning>
  नोट - आप केवल उन contracts को search कर सकते हैं जो Tenderly या
  Etherscan पर सार्वजनिक रूप से सत्यापित हैं। [**Tenderly पर contract को कैसे सत्यापित करें, इसके बारे में यहाँ अधिक पढ़ें।**](/contract-verification/overview)
</Warning>

यदि contract सार्वजनिक रूप से सत्यापित नहीं है, तो आप इसे Tenderly के साथ उपयोग करने में सक्षम होने के लिए स्वयं कर सकते हैं। यदि project open-source है (जैसे Cover), तो आप project के [GitHub repo](https://github.com/CoverProtocol/cover-token-mining) पर जा सकते हैं, वह contract खोजें जिसका आप उपयोग करना चाहते हैं (और उसका सोर्स कोड) और स्वयं इसे सत्यापित करें।

![](https://lh4.googleusercontent.com/vWVW6dAj1J6d83juyoXZ3cR9DTMmVgXu9PYHUUL4_Mv5LRAJ8wnXSckv72tEv-C96zOeutweZaLAx4OEaVBon1PkZOGMBmPwKLlTBJuPEAaPkZSDjwwtip3Kzx1d8B-UzYA7wRkE)

![](https://lh4.googleusercontent.com/C6BHcXHp8NHQmkb7kJP2vwNDi86mVgb-GyHb5Fp9OtddF3anpTTCdkERiNXAGYXnuhippPJKPuxf6a9RW1GIu91nECQWoV033C7gg1GHnz5tsoEP3BkkcMMiAHDCUspbmMz-BVUf)

अब जब हमारे पास वह contract है जिसे हम Tenderly में import करना चाहते हैं, तो अपने Dashboard पर जाएँ और बाईं ओर **Contracts** tab पर क्लिक करें, और फिर ऊपर दाईं ओर **Add Contract** बटन पर क्लिक करें:

<img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/Screenshot%202021-12-01%20at%2010.28.37.webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=51b1b58ec98df00a2b0526ec24d6a581" alt="" width="2521" height="787" data-path="images/Screenshot 2021-12-01 at 10.28.37.webp" />

आप अपने Dashboard के माध्यम से, या CLI के माध्यम से contract के code को upload और सत्यापित कर सकते हैं [\[अधिक जानकारी यहाँ\]](/contract-verification/overview):

<img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/Screenshot%202021-12-01%20at%2010.30.25.webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=24ce923a3732175540cccc93975e4001" alt="" width="2521" height="787" data-path="images/Screenshot 2021-12-01 at 10.30.25.webp" />

<img src="https://mintcdn.com/tenderly/XsEZlaGXYskrtN68/images/Screenshot%202021-12-01%20at%2010.30.30.webp?fit=max&auto=format&n=XsEZlaGXYskrtN68&q=85&s=07faeb1cb135bdf6fca956ac178441cf" alt="" width="2521" height="927" data-path="images/Screenshot 2021-12-01 at 10.30.30.webp" />

अब, contract को import और सत्यापित करने के बाद, आइए hack का विश्लेषण करें। हम जानते हैं कि bug deposit function के cache में मौजूद था, इसलिए हम उस function को simulate करते हैं। जैसा कि हम नीचे screenshot में देख सकते हैं, execution के बाद यह `Blacksmith: pool does not exist` के साथ विफल हो गया।

![](https://lh5.googleusercontent.com/JlFsuawkRAxjCnd7sHefFA9n-WpUOPMWIlnXb_IBOrdvQI8OFvRvTsWPH02p9qy1tmqDf8HnwVgJM2hK3x2iAmvWXNLj-qNLqDzyUmBBG4nbRAmkjfkpRGkh8748cFr052jEoaBL)

अब, आइए Tenderly Debugger में इस error को खोलें। line 118 पर हम deposit function में `Pool memory pool = pools[_lpToken];` देखते हैं जहाँ data cache होता है, और बाद में line 125 पर अपडेट होता है जहाँ हम `_claimCoverRewards(pool, miner);` देखते हैं

Contract ने cache data का उपयोग किया क्योंकि data स्वयं memory में रहा; इसीलिए बाद में contract ने उस data का उपयोग करके function की गणना की। Cache को अपडेट नहीं किया गया जिसके परिणामस्वरूप यह hack हुआ:

```solidity title="example.sol" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
miner.rewardWriteoff = miner.amount.mul(pool.accRewardsPerToken).div(CAL_MULTIPLIER);
```

```solidity title="example.sol" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
miner.bonusWriteoff = miner.amount.mul(bonusToken.accBonusPerToken).div(CAL_MULTIPLIER);
```

![](https://lh3.googleusercontent.com/6jPAgWs9ZLNkM7PzW_g-0kR0Wy5kYMtk80huWk_KzsfpF7WBTrhE3VIWvPTI0bwVQmR25TLsARV-Ea3f2mK_kwcYESQEjxKebHv19YbNEuG-Jr0MJQ4t_LsxV-Q83rB_SC1NGV1v)

```solidity title="example.sol" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
function deposit(address _lpToken, uint256 _amount) external override {
    require(block.timestamp >= START_TIME, "Blacksmith: not started");
    require(_amount > 0, "Blacksmith: amount is 0");

    Pool memory pool = pools[_lpToken];

    require(pool.lastUpdatedAt > 0, "Blacksmith: pool does not exists");
    require(IERC20(_lpToken).balanceOf(msg.sender) >= _amount, "Blacksmith: insufficient balance");

    updatePool(_lpToken);

    Miner storage miner = miners[_lpToken][msg.sender];
    BonusToken memory bonusToken = bonusTokens[_lpToken];

    _claimCoverRewards(pool, miner);
    _claimBonus(bonusToken, miner);

    miner.amount = miner.amount.add(_amount);

    // update writeoff to match current acc rewards/bonus per token
    miner.rewardWriteoff = miner.amount.mul(pool.accRewardsPerToken).div(CAL_MULTIPLIER);
    miner.bonusWriteoff = miner.amount.mul(bonusToken.accBonusPerToken).div(CAL_MULTIPLIER);

    IERC20(_lpToken).safeTransferFrom(msg.sender, address(this), _amount);
    emit Deposit(msg.sender, _lpToken, _amount);
}

```

* Hack से कुछ घंटे पहले liquidity mining के लिए एक नया pool approved हुआ था। यह pool पूरी तरह से सामान्य है लेकिन चूँकि यह नया था, blacksmith contract के पास इस pool का कोई LP token नहीं था।
* हमलावर ने इस pool के कुछ tokens को Blacksmith contract में जमा कर दिया।
* Blacksmith contract प्रति-token के आधार पर rewards का ट्रैक रखता है। यदि बहुत सारे tokens locked हैं, तो प्रति-token reward छोटा होगा। यदि बहुत कम tokens locked हैं, तो प्रति-token reward बड़ा होगा। संबंधित variable को `accRewardsPerToken` कहा जाता है और इसकी गणना `totalPoolRewards / totalTokenBalance` के रूप में की जाती है।
* हमलावर ने फिर Blacksmith contract से लगभग सभी LP tokens निकाल लिए, `totalTokenBalance` राशि को लगभग शून्य कर दिया।
* हमलावर ने फिर इस pool के कुछ tokens को Blacksmith contract में फिर से जमा किया। यहीं पर bug ने अपने असली रंग दिखाए। चूँकि पिछले transaction में `totalTokenBalance` बहुत कम हो गया था, इसलिए नए-गणना किए गए `accRewardsPerToken` में तेज़ी से वृद्धि हुई। Contract `accRewardsPerToken` के प्रभाव को नियंत्रण में रखने के लिए `rewardWriteoff` का उपयोग करता है। हालाँकि, bug के कारण, `rewardWriteoff` मान की गणना करते समय `accRewardsPerToken` का पुराना (छोटा) मान उपयोग किया गया था। इसके कारण, `accRewardsPerToken` का बड़ा मान अनियंत्रित रहा।
* हमलावर ने फिर अपने rewards निकाले। चूँकि `accRewardsPerToken` में एक बड़ा, अनियंत्रित मान था, system से भुगतान किया गया कुल reward inflate हो गया और **contract ने अंततः 40,796,131,214,802,500,000 COVER tokens mint कर दिए**।

<Note>
  इस hack breakdown के अंतिम भाग के लिए Mudit Gupta को धन्यवाद - [उनके ब्लॉग पर इसके बारे में
  अधिक पढ़ें](https://mudit.blog/cover-protocol-hack-analysis-tokens-minted-exploit/) :)
</Note>
