<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Librechain]]></title><description><![CDATA[Latest news regarding blockchain, cryptocurrency and cybersecurity. No BS, hype or gimmicks. Raw information.]]></description><link>https://librehash.xyz</link><generator>RSS for Node</generator><lastBuildDate>Mon, 20 Apr 2026 16:27:19 GMT</lastBuildDate><atom:link href="https://librehash.xyz/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Bitcoin March 2025 Price Analysis Update]]></title><description><![CDATA[There's been a ton of volatility surrounding Bitcoin's price as of recent, so we're going to check that out and see what's really going on. I assume that this price analysis is coming at a good time for most since there appears to be peak confusion i...]]></description><link>https://librehash.xyz/bitcoin-march-2025-price-analysis-update</link><guid isPermaLink="true">https://librehash.xyz/bitcoin-march-2025-price-analysis-update</guid><category><![CDATA[Bitcoin]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Price Analysis]]></category><category><![CDATA[Technical Analysis]]></category><category><![CDATA[markets]]></category><category><![CDATA[stocks]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[code]]></category><category><![CDATA[trading, ]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Wed, 05 Mar 2025 06:55:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157676152/eaaec5c2-203e-40a7-bee4-4a1a57aea83e.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There's been a ton of volatility surrounding Bitcoin's price as of recent, so we're going to check that out and see what's really going on. I assume that this price analysis is coming at a good time for most since there appears to be <strong>peak</strong> confusion in the minds of traders currently at the time of writing.</p>
<h3 id="heading-confirming-the-double-top-formation">Confirming the Double Top Formation</h3>
<p>Over the past few days and weeks, multiple traders in the crypto space have identified a double top formation on Bitcoin's chart (daily resolution). A careful analysis confirms this observation, which carries significant implications for Bitcoin's price trajectory.</p>
<p>Let's take a look at the main chart to understand why this double top formation has materialized on the daily resolution (which indeed suggests potential bearish movement ahead).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741156985207/42b3401f-284b-49c8-9f86-1167ae512a27.png" alt class="image--center mx-auto" /></p>
<p>As we can see in the chart above, Bitcoin's price has clearly formed two nearly equivalent localized highs over the past few weeks - a classic double top pattern.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157007239/d0f8455e-e466-4bb4-bcea-58d882496435.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Specifically, the first 'top' occurred on December 18th, 2024 and the second 'top' was on January 22nd, 2025</em></p>
</blockquote>
<p>This double top formation is particularly noteworthy because it meets the key criteria for this pattern. To understand why this is significant, let's review the technical definition of a double top chart formation.</p>
<h2 id="heading-understanding-the-double-top-formation">Understanding the Double Top Formation</h2>
<p>Per <a target="_blank" href="https://www.investopedia.com/terms/d/doubletop.asp">Investopedia</a>, a double top, "<em>is an extremely bearish technical reversal pattern that forms after an asset reaches a high price two consecutive times with a moderate decline between the two highs. It is</em> <strong>confirmed once the asset's price falls below a support level equal to the low between the two prior highs</strong>."</p>
<p><a target="_blank" href="https://chartschool.stockcharts.com/table-of-contents/chart-analysis/chart-patterns/double-top-reversal">Per Stockcharts</a>, "<em>After the first peak, there is generally a 10-20% decline. Volume on the decline is inconsequential. The lows are sometimes rounded or drawn out a bit, which can signify tepid demand.</em>"</p>
<p>Taking a closer look at the charts, we can confirm that there was a -10 to 20% decline in the price from the first localized top it made to the 'trough' (that support point that the price bounces from before re-testing that same high and getting rejected the second time around).</p>
<p>See below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157045179/e1b49d33-3da9-465f-bb33-d7511c304fa4.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>As the chart above reflects, the price depreciated -13.09% to test the $93k as a support before returning for a second test of the previous high that had been notched</em> ($106-108k).</p>
</blockquote>
<p>Referring back to Stockcharts, the site tells us that, "<em>The subsequent decline from the second peak should witness an expansion in volume and/or an accelerated descent, perhaps marked by a gap or two. Such a decline shows that demand forces are weaker than supply, and a support test is imminent.</em>"</p>
<p>More specifically, "<em>The Even after trading down to support, the Double Top Reversal and trend reversal are still incomplete. Breaking support from the lowest point between the peaks</em> <strong>completes the Double Top Reversal</strong>. <em>This should occur with increased volume and/or accelerated descent.</em>"</p>
<p>Let's take a look at our chart again to see whether Bitcoin's price action broke below the support that was tested after the pushback from the first high that was created. If so, then the impact of the Double Top formation <strong>is complete</strong> (i.e., we can consider the net bearish impact to be wherever the price lands after it breaks south of the support that was formed prior).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157067097/1a45ac0e-2ab9-4521-8c03-a5b08149df33.png" alt class="image--center mx-auto" /></p>
<p>Taking a closer look, we can see the price depreciated another -9% once it fell below the support that was created after the push back from the first localized high that was created for this double top formation.</p>
<p>The support that was tested and established when the price fell below the support for this double top chart formation (on the <strong>daily resolution</strong>), is $87k.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157155083/31c1176c-b728-4dda-8751-438616816226.png" alt class="image--center mx-auto" /></p>
<p>From that point forward, the price made a swift recovery before re-testing that former support as an overhead resistance. When this occurred, the price was successfully pushed back, finalizing all features and traits of a double top chart pattern.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157168464/4aab99c2-9f54-42ab-bc64-cd65c02c08a7.png" alt class="image--center mx-auto" /></p>
<p>Now the question we have from this point is 'what to expect next?'.</p>
<p>To find out the answer to that, we're going to employ a wide host of custom indicators and tools to help facilitate our reading of Bitcoin's price action via technical analysis. This analysis tends to be <strong>extremely accurate</strong> (this is verifiable for anyone that elects to look at prior price analyses that have been published on Twitter, Discord, Telegram, TradingView and elsewhere over time).</p>
<h2 id="heading-ema-indicators-underscore-recent-bearish-price-action">EMA Indicators Underscore Recent Bearish Price Action</h2>
<p>Since EMA indicators are <strong>lookback</strong> indicators, they aren't necessarily meant to <strong>forecast future price action</strong> off the strength of these readings (<em>have to be careful to remain aware of this</em>).</p>
<p>If we look at Bitcoin's price action on the daily resolution, we'll see that the EMA-12, EMA-26, EMA-50, EMA-100 and EMA-200 are all at values that are above where Bitcoin is trading at, at the time of writing during this period (daily candle; March 5th, 2025 UTC).</p>
<p>To get a better idea for what I mean, see below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157282595/e8e6c2af-c40d-4d64-b3fd-cf86c78723ca.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Above we can see the EMA-12's value is $89,549 while Bitcoin is currently trading at $87,400</em>.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157309955/35f7f596-844b-490a-9826-735aa9edcb62.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Above, we can see that the EMA-26's value is at $92,548 while Bitcoin is currently trading at $87,400</em></p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157360466/bcb5dc8a-84dc-4283-aa68-d492ec591093.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Above, we can see that the EMA-50's value is at $94,585 while Bitcoin is currently trading at $87,400</em>.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157393698/bc5b5739-b934-4e3b-824a-7381c6d435f7.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Above, we can see that the EMA-100's value is at $93,028 while Bitcoin is trading at $87,520</em>.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157426615/1f1263e6-90bb-41cc-9b19-0627fe007999.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Here, in our only deviation from the pattern established by the other EMA indicators, we can see that Bitcoin is currently trading above the notional value of the EMA-200 on the daily resolution. Specifically, the EMA-200's current value is $85,740 while the price of Bitcoin is still hovering at $87.513 at the time of writing.</em></p>
</blockquote>
<p>Everything we wrote above means a few things. Specifically:</p>
<ol>
<li><p>Since the EMA-200's value is below where the price is at currently at the time of writing, that's going to serve as another market of support (<em>the value of the EMA's on the daily always serve as either support or resistance points contingent on whether they are above or below the price at that point in time</em>).</p>
</li>
<li><p>Following from what we wrote in #1, we can deduce that all of the other EMA values will serve as various overhead resistance points. Among all of them, the <strong>strongest resistance</strong> will be posed by the EMA-50. Why? Not entirely sure, to be honest. I can just tell you from observation after charting Bitcoin for nearly 10+ years, that the EMA-50 tends to have the strongest impact on price action, whether as an impediment (via overhead resistance) or immobile support (via underlying support).</p>
</li>
<li><p>The EMA-50 is still well above the EMA-100 and EMA-200. This means that we're nowhere near <strong>double cross territory</strong>. That's good, because that would reflect a higher level of bearishness than we'd wanna see (if we're bull market advocates).</p>
</li>
</ol>
<p>With all of that being said, many of the other indicators for Bitcoin on the daily resolution provide a <strong>very bullish reflection</strong>. Let's take a look at some of those indicators for a second to get a greater feel for where Bitcoin is headed in the not so distant future.</p>
<h2 id="heading-librehash-reversion-ribbon-v2">Librehash Reversion Ribbon V2</h2>
<p>If we take a look at the Reversion Ribbon (custom indicator) we can see that there was a <strong>very faint bullish signal</strong> on Bitcoin that appeared recently. But what we can see on the chart from this indicator, currently, is not enough for us to justify entering into a bullish position yet (or a bearish one either).</p>
<p>Check it out below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157457852/58d2954a-ef78-48b8-9cbb-943f621c6544.png" alt class="image--center mx-auto" /></p>
<p>As we can see from the chart above:</p>
<ul>
<li><p>The ribbon is currently below the histogram (zero point), which belies bearish price action.</p>
</li>
<li><p>The ribbon did exhibit a bullish cross over recently (changing the color of the ribbon from red to green). That occurred between March 1st and March 2nd. However, as we can see the bullish divergence that emerged was <strong>very short lived</strong>.</p>
</li>
<li><p>Moving forward, we can see that the ribbon has begun converging just one period after it made its bullish crossover with some sizable divergence behind it.</p>
</li>
</ul>
<p>As of right now, there's not really enough information that we can glean from the indicator to say that its forecasting bullish or bearish price action in the near future. However, one thing that we can say is that observation tells us that there's been a ton of bearish price action over the past 2-3 periods.</p>
<p>Specifically, we can see that the green candles are only colored <strong>light green</strong> (this indicator changes the shade of the candle based on the strength of the underlying price action [i.e., very bullish = green; very bearish = red]). In addition, for those two large daily candles that formed on March 2nd and March 3rd, both were given <em>red outlines</em>. This is essentially our indicator telling us that despite the bullish price action, there was strong underlying bearish sentiment.</p>
<p>Take a closer look below here:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157480840/cb2ced8e-4588-412a-9acf-865f69de0bee.png" alt class="image--center mx-auto" /></p>
<p>So, thus far, we can say that the Reversion Ribbon v2 isn't dictating any particularly bullish price action.</p>
<p>Let's take a loot at some of our other indicators here (and also speed up this analysis so that we can get to the point a bit quicker as there are other things that we have to get done right now at the time of writing).</p>
<h2 id="heading-reading-the-rest-of-our-indicators">Reading the Rest of Our Indicators</h2>
<p>We'll start with some of our oscillators to get a better idea of how to forecast Bitcoin's price action in the not so distant future.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741157497425/a8ede123-5242-431c-adcc-f1f540c72f50.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>Above we can see the Cryptomedication Volatility RSI. Based on how the indicator is meant to be evaluated and read.</p>
</blockquote>
<p>Its worth noting the following with this indicator:</p>
<ol>
<li><p><strong>Volatility Level</strong>: The indicator appears to be at a relatively low level, suggesting decreased volatility in Bitcoin's price action currently. As explained in the definition, "as the line nears the bottom, so does volatility."</p>
</li>
<li><p><strong>Price Contraction</strong>: Since this indicator tracks both expansion/contraction in price and increase/decrease in volatility simultaneously, the current position suggests we're in a period of price contraction.</p>
</li>
<li><p><strong>Trend Indication</strong>: The Volatility RSI's current trajectory can help identify potential entry/exit points. The relatively low reading suggests we may be approaching a period where a new trend could emerge.</p>
</li>
</ol>
<h2 id="heading-our-trade-strategy">Our Trade Strategy</h2>
<p>We have a two pronged strategy that is designed to 'go with the flow' of future price action for Bitcoin.</p>
<p>Bitcoin is currently at a critical juncture following a confirmed double top formation with peaks at $106-108k. Price has broken below the $93k support level and is currently trading at $87,400, positioned between multiple EMA resistances above and the EMA-200 support below. Technical indicators suggest decreased volatility and potential for a new directional move in the near term.</p>
<h3 id="heading-trading-strategy-dual-scenario-approach">Trading Strategy: Dual Scenario Approach</h3>
<h4 id="heading-scenario-1-bearish-continuation-primary-scenario">Scenario 1: Bearish Continuation (Primary Scenario)</h4>
<p><strong>Entry Conditions:</strong></p>
<ul>
<li><p>Current price level ($87,400) or on rejection from EMA-12 resistance ($89,583)</p>
</li>
<li><p>Confirmation: Daily close below $87,000</p>
</li>
<li><p>Additional validation: Failure of price to reclaim EMA-12 on a retest</p>
</li>
</ul>
<p><strong>Position Management:</strong></p>
<ul>
<li><p><strong>Stop Loss:</strong> $89,600 (just above EMA-12)</p>
</li>
<li><p><strong>Risk per trade:</strong> 2.5% of trading capital</p>
</li>
<li><p><strong>Target 1:</strong> $82,000 (25% of position) - R/R ratio: 2.7:1</p>
</li>
<li><p><strong>Target 2:</strong> $78,500 (50% of position) - R/R ratio: 4.5:1</p>
</li>
<li><p><strong>Target 3:</strong> $76,000 (25% of position) - R/R ratio: 5.8:1</p>
</li>
</ul>
<p><strong>Technical Rationale:</strong></p>
<ul>
<li><p>Complete double top formation with break below crucial $93k support</p>
</li>
<li><p>Price trading below four major EMAs (12, 26, 50, 100)</p>
</li>
<li><p>Reversion Ribbon below zero with bearish candle coloring</p>
</li>
<li><p>Recent failed retest of $93k as resistance</p>
</li>
<li><p>Measured move from double top projects lower prices</p>
</li>
</ul>
<p><strong>Risk Invalidation:</strong></p>
<ul>
<li><p>Daily close above $89,600 (EMA-12)</p>
</li>
<li><p>Significant increase in Volatility RSI with bullish price action</p>
</li>
</ul>
<h4 id="heading-scenario-2-bullish-reversal-alternative-scenario">Scenario 2: Bullish Reversal (Alternative Scenario)</h4>
<p><strong>Entry Conditions:</strong></p>
<ul>
<li><p>Price breaks and closes above EMA-12 ($89,583)</p>
</li>
<li><p>Confirmation: Successful retest of EMA-12 as support</p>
</li>
<li><p>Additional validation: Volatility RSI showing expansion from low levels</p>
</li>
</ul>
<p><strong>Position Management:</strong></p>
<ul>
<li><p><strong>Entry:</strong> $89,700 (after confirmation)</p>
</li>
<li><p><strong>Stop Loss:</strong> $85,700 (just below EMA-200)</p>
</li>
<li><p><strong>Risk per trade:</strong> 2% of trading capital</p>
</li>
<li><p><strong>Target 1:</strong> $92,500 (EMA-26) - 50% of position - R/R ratio: 0.7:1</p>
</li>
<li><p><strong>Target 2:</strong> $94,600 (EMA-50) - 30% of position - R/R ratio: 1.2:1</p>
</li>
<li><p><strong>Target 3:</strong> $98,000 (psychological level) - 20% of position - R/R ratio: 2.1:1</p>
</li>
</ul>
<p><strong>Technical Rationale:</strong></p>
<ul>
<li><p>Price holding above critical EMA-200 support</p>
</li>
<li><p>No "double cross" in EMAs (EMA-50 still above EMA-100/200)</p>
</li>
<li><p>Low volatility period (per Volatility RSI) often precedes significant moves</p>
</li>
<li><p>Potential for contrarian move against obvious bearish pattern</p>
</li>
</ul>
<p><strong>Risk Invalidation:</strong></p>
<ul>
<li><p>Daily close below EMA-200 ($85,740)</p>
</li>
<li><p>Acceleration of bearish momentum on high volume</p>
</li>
</ul>
<h3 id="heading-key-price-levels-to-monitor">Key Price Levels to Monitor</h3>
<p><strong>Support Levels:</strong></p>
<ul>
<li><p>$87,000 (Current established support)</p>
</li>
<li><p>$85,740 (EMA-200) - <strong>CRITICAL</strong></p>
</li>
<li><p>$82,000 (Projected target based on pattern measurement)</p>
</li>
<li><p>$78,500 (Psychological support near $80,000)</p>
</li>
</ul>
<p><strong>Resistance Levels:</strong></p>
<ul>
<li><p>$89,583 (EMA-12) - <strong>IMMEDIATE</strong></p>
</li>
<li><p>$92,548 (EMA-26)</p>
</li>
<li><p>$93,000 (Former support, now resistance)</p>
</li>
<li><p>$94,604 (EMA-50) - <strong>STRONG</strong></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Understanding How Upgradable Smart Contracts Work (WazirX)]]></title><description><![CDATA[One popular staple of smart contracts is the 'upgradable' smart contract. For those that are familiar with smart contract development, you've likely encountered these types of contracts before.
However, if you have not - then this is going to serve a...]]></description><link>https://librehash.xyz/understanding-how-upgradable-smart-contracts-work-wazirx</link><guid isPermaLink="true">https://librehash.xyz/understanding-how-upgradable-smart-contracts-work-wazirx</guid><category><![CDATA[wazirx]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Crypto exchange development]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[Solana]]></category><category><![CDATA[Cryptography]]></category><category><![CDATA[Digital currency]]></category><category><![CDATA[decentralized]]></category><category><![CDATA[hacking]]></category><category><![CDATA[hack]]></category><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Solidity]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 04 Oct 2024 00:40:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002093187/5c3c42bb-2c26-4e4d-8049-210ac15af22b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One popular staple of smart contracts is the 'upgradable' smart contract. For those that are familiar with smart contract development, you've likely encountered these types of contracts before.</p>
<p>However, if you have not - then this is going to serve as a brief guide on how they work and what their purpose is. We're also going to cover some of the potential pitfalls and catch 22's associated with upgradable smart contracts. Our rationale for doing so is to provide greater context to the WazirX hack.</p>
<h3 id="heading-concept-of-upgradable-smart-contracts">Concept of Upgradable Smart Contracts</h3>
<p>In general, smart contracts are designed to be 'immutable'. This means that once the smart contract is deployed on the blockchain, whatever code that's written in it is fixed in stone.</p>
<p>Thus, the concept of the 'upgradable' smart contract was introduced to allow developers to 'update' the actual code that gets executed when someone makes a call upon a specific smart contract.</p>
<h4 id="heading-proxy-and-logic-smart-contracts">Proxy and Logic Smart Contracts</h4>
<p>In order to construct this pipeline, multiple different smart contracts are deployed to operate in concert with one another.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002110119/094e190a-301f-4442-8681-cc8d0d5404cd.png" alt class="image--center mx-auto" /></p>
<p>As can be seen in the illustration above, these types of smart contract orchestrations (<em>at least</em>) involve two contracts, which are known as the - <em>proxy contract</em> and <em>implementation contract</em>.</p>
<p>The proxy contract is the 'front-facing' contract where users issue all their calls. Calls made upon the <strong>proxy contract</strong> then get forwarded to the <strong>implementation contract</strong> (<em>which holds the business logic of the proxy contract</em>).</p>
<p>This is the part where things get a bit confusing, but I'm going to try my best to break this down (<em>again</em>) in a digestible manner. The first concept we need to grasp is that even though calls are made to the proxy contract, the actual functions that we need to call are likely defined in our implementation contract.</p>
<p>So, for example, if we wanted to transfer an ERC20 token for some sort of DeFi protocol we've set up using this orchestration, then the likely function we'd be calling is a <code>_transfer</code> function.</p>
<p>Below is an example of such:</p>
<pre><code class="lang-solidity"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">_transfer</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> sender, <span class="hljs-keyword">address</span> recipient, <span class="hljs-keyword">uint256</span> amount</span>) <span class="hljs-title"><span class="hljs-keyword">internal</span></span> </span>{
    <span class="hljs-built_in">require</span>(sender <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-string">"ERC20: transfer from the zero address"</span>);
    <span class="hljs-built_in">require</span>(recipient <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-string">"ERC20: transfer to the zero address"</span>); 
    _beforeTokenTransfer(sender, recipient, amount);
    <span class="hljs-keyword">uint256</span> senderBalance <span class="hljs-operator">=</span> _balances[sender];
    <span class="hljs-built_in">require</span>(senderBalance <span class="hljs-operator">&gt;</span><span class="hljs-operator">=</span> amount, <span class="hljs-string">"ERC20: transfer amount exceeds balance"</span>);
    _balances[sender] <span class="hljs-operator">=</span> senderBalance <span class="hljs-operator">-</span> amount;
    _balances[recipient] <span class="hljs-operator">+</span><span class="hljs-operator">=</span> amount;
    <span class="hljs-keyword">emit</span> Transfer(sender, recipient, amount);
    _afterTokenTransfer(sender, recipient, amount);
}
</code></pre>
<p>As we can see above, the <code>_transfer</code> function is fully defined above. This function exists within the <strong>implementation contract</strong>. However, this is not the contract that we're going to be making a call on directly.</p>
<p>Below is an example of a (<em>very basic</em>) proxy contract that could be associated with the example implementation contract provided above.</p>
<pre><code class="lang-solidity"><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>

<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"</span>;

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">MyTokenProxy</span> <span class="hljs-keyword">is</span> <span class="hljs-title">TransparentUpgradeableProxy</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _logic, <span class="hljs-keyword">address</span> admin_, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> _data</span>)
        <span class="hljs-title">TransparentUpgradeableProxy</span>(<span class="hljs-params">_logic, admin_, _data</span>)
    </span>{}
}
</code></pre>
<p>As we can see in the proxy contract above, there are no functions governing the <code>_transfer</code> function. However, if we did want to transfer tokens in this orchestration, then we would be making that call on <strong>this proxy contract</strong> here.</p>
<h4 id="heading-how-the-fallback-function-works">How the Fallback Function Works</h4>
<p>Every Ethereum smart contract contains something called a 'fallback' function. Essentially, this function is triggered in either of the two following conditions:</p>
<ol>
<li><p>Ethereum is sent to a smart contract without any associated data.</p>
</li>
<li><p>A function is called on a smart contract that isn't defined in said smart contract.</p>
</li>
</ol>
<p>Below is a very basic example implementation of a generic smart contract that contains a <code>fallback</code> function (<em>which typically is not defined or labeled as 'fallback' within the smart contract</em>).</p>
<p>Check it out below:</p>
<pre><code class="lang-solidity"><span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">ExampleContract</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">FallbackCalled</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> sender, <span class="hljs-keyword">uint</span> amount, <span class="hljs-keyword">bytes</span> data</span>)</span>;

    <span class="hljs-comment">// FALLBACK FUNCTION!!!</span>
    <span class="hljs-function"><span class="hljs-keyword">fallback</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
        <span class="hljs-keyword">emit</span> FallbackCalled(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">data</span>);
    }
}
</code></pre>
<blockquote>
<p><strong>What the Smart Contract Does When the Fallback Function is Triggered</strong>: <em>It emits the</em> <code>FallbackCalled</code> event, logging the sender’s address (<code>msg.sender</code>), the amount of Ether sent (<code>msg.value</code>), and any data sent with the transaction (<a target="_blank" href="http://msg.data"><code>msg.data</code></a>).</p>
</blockquote>
<p><strong>Quick Dirty on Fallback Functions</strong>:</p>
<ol>
<li><p><em>They have no need for a name.</em></p>
</li>
<li><p><em>They can be externally called</em>.</p>
</li>
<li><p><em>Per contract, there can only be one or zero fallback functions.</em></p>
</li>
<li><p><em>The functions are automatically triggere dwhen called by another contract given that the called function has no name.</em></p>
</li>
<li><p><em>The functions also allow for</em> <strong>arbitrary logic to be included</strong>.</p>
</li>
<li><p><em>It can also be triggered if a token(s) is sent to a contract that has fallback functions with no declared</em> <code>receive()</code> <em>function and no accompanying</em> <code>calldata</code>.</p>
</li>
</ol>
<blockquote>
<p><strong>Source</strong>: *<a target="_blank" href="https://info.etherscan.com/what-is-a-fallback-function/">https://info.etherscan.com/what-is-a-fallback-function/</a></p>
</blockquote>
<h3 id="heading-breaking-down-the-infamous-delegatecall">Breaking Down the Infamous DelegateCall</h3>
<p>The most important facet of the smart contract upgradable proxy pattern that we're going to focus on in this piece is the <code>delegatecall</code> function.</p>
<p>As noted before, whenever interacting with a smart contract orchestration that utilizes the proxy upgradable pattern, the proxy is going to serve as a the front-facing contract that users interact with. Calls made upon this contract are typically done based on the <strong>logic</strong> contained within the <strong>implementation contract</strong> that the proxy forwards calls to (<em>via the</em> <code>fallback</code> <em>function, however that's setup in the proxy</em>).</p>
<p>This is where the <code>delegatecall</code> function becomes relevant (<em>making it the most relevant function that we're going to focus on here</em>).</p>
<p>In the context of a proxy smart contract in Ethereum, the <code>delegatecall</code> function is a low-level function that allows a contract to execute code from another contract while preserving the context (i.e., <code>msg.sender</code>, <code>msg.value</code>, and <code>storage</code>) of the calling contract.</p>
<p><strong>Here's a detailed breakdown of how</strong> <code>delegatecall</code> <strong>is used within a proxy contract</strong>:</p>
<ol>
<li><p><strong>Proxy Pattern</strong>: The proxy pattern involves a proxy contract that does not contain the actual business logic but instead forwards calls to another contract (<em>often referred to as the implementation or logic contract</em>). This pattern is commonly used for upgradability, where the logic contract can be replaced without changing the proxy contract's address.</p>
</li>
<li><p><strong>Preserving State</strong>: When using <code>delegatecall</code>, the storage of the proxy contract is used instead of the storage of the logic contract. This means that any state changes made by the logic contract will affect the proxy contract's storage.</p>
</li>
<li><p><strong>Execution Context</strong>: The <code>delegatecall</code> function ensures that the <code>msg.sender</code> and <code>msg.value</code> remain the same as if the call was made directly to the proxy contract. This is important for maintaining the correct context, especially for access control and payment forwarding.</p>
</li>
<li><p><strong>Function Call Forwarding</strong>: In a typical proxy contract implementation, the fallback function is overridden to use <code>delegatecall</code> to forward any call to the logic contract.</p>
</li>
</ol>
<p><em>Below is an example of a smart contract that contains the relevant</em> <code>delegatecall</code> <em>functionality within the fallback function of the proxy</em>:</p>
<pre><code class="lang-solidity"><span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.0;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Proxy</span> </span>{
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">public</span> implementation;

    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _implementation</span>) </span>{
        implementation <span class="hljs-operator">=</span> _implementation;
    }

    <span class="hljs-function"><span class="hljs-keyword">fallback</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
        <span class="hljs-keyword">address</span> _impl <span class="hljs-operator">=</span> implementation;
        <span class="hljs-built_in">require</span>(_impl <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>), <span class="hljs-string">"Implementation contract not set"</span>);

        <span class="hljs-comment">// Delegate the call to the implementation contract</span>
        (<span class="hljs-keyword">bool</span> success, ) <span class="hljs-operator">=</span> _impl.<span class="hljs-built_in">delegatecall</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">data</span>);
        <span class="hljs-built_in">require</span>(success, <span class="hljs-string">"Delegatecall failed"</span>);
    }

    <span class="hljs-comment">// Optional: receive function to handle plain ether transfers</span>
    <span class="hljs-function"><span class="hljs-keyword">receive</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{}
}
</code></pre>
<p>In this example:</p>
<ul>
<li><p>The <code>implementation</code> address is set to point to the logic contract.</p>
</li>
<li><p>The <code>fallback</code> function is defined to catch all calls to the proxy contract and forward them to the logic contract using <code>delegatecall</code>.</p>
</li>
<li><p>The <a target="_blank" href="http://msg.data"><code>msg.data</code></a> is passed to the logic contract, which contains the function selector and arguments for the intended function call.</p>
</li>
</ul>
<ol start="5">
<li><strong>Upgradability</strong>: The proxy contract can be upgraded by changing the <code>implementation</code> address to point to a new logic contract. This allows the proxy contract to forward calls to the new logic contract without changing the proxy's address, thereby preserving the contract's state and external interfaces.</li>
</ol>
<h3 id="heading-looking-at-an-example-wazirx-2-implementation-of-the-proxy-upgradable-smart-contract-pattern">Looking at an Example (WazirX 2) Implementation of the Proxy Upgradable Smart Contract Pattern</h3>
<p>Relevantly, WazirX - the Indian cryptocurrency exchange that recently suffered a $230 million smart contract exploit, had employed a proxy upgradable structure to govern the custody and transfer of their Ethereum assets.</p>
<p>However, to give us some better context and understanding on how such a smart contract orchestration works in practice, we're going to look at one of their pre-hack transactions.</p>
<p>Specifically <a target="_blank" href="https://etherscan.io/tx/0xfe10c646ba26b262a82b7223b46ed087eceb844520baf1b1dfae28bb84104f26">this one</a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002133067/95d84037-e2ff-478d-a015-0bff08d2325f.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><a target="_blank" href="https://etherscan.io/search?q=0xfa377a00729d54d167ebbc37a42f040c9237c56ade00843f1cc24421e2bf2d81">https://etherscan.io/search?q=0xfa377a00729d54d167ebbc37a42f040c9237c56ade00843f1cc24421e2bf2d81</a></p>
</blockquote>
<p>Please note that WazirX's smart contract (<code>0x27fD43</code>) is the <strong>proxy contract</strong> for their upgradable proxy pattern implementation.</p>
<p>If we take a look at the 'internal txns' (internal transactions) panel provided on Etherscan for this <a target="_blank" href="https://etherscan.io/tx/0xfa377a00729d54d167ebbc37a42f040c9237c56ade00843f1cc24421e2bf2d81/advanced#internal">specific transaction</a>, we'll see that a <code>delegatecall</code> was triggered by this transaction.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002148626/7f1f80ad-5a54-4caa-bdca-19c6edfdc3d9.png" alt class="image--center mx-auto" /></p>
<p>To be clear, in this specific transaction, there are two <code>delegatecall</code> made to two different smart contracts.</p>
<p>The first one (<em>at the bottom</em>), <a target="_blank" href="https://etherscan.io/address/0x43506849d7c04f9138d1a2050bbf3a0c054402dd">here</a> governs the transfer of $USDC (<em>which is also orchestrated by an upgradable proxy smart contract pattern</em>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002167149/277b5cab-688e-4d4b-9c4a-9b269fbc1007.png" alt class="image--center mx-auto" /></p>
<p>When WazirX attempts to transfer USDC using their upgradable proxy, the following sequence of calls occurs:</p>
<ol>
<li><p><strong>First Call to the WazirX Proxy Contract</strong>:    - You initiate a call to your proxy contract to perform the USDC transfer.    - Your proxy contract uses <code>delegatecall</code> to forward this call to its implementation contract.</p>
</li>
<li><p><strong>Call to USDC Proxy Contract</strong>:    - The implementation contract of your proxy contract contains the logic to transfer USDC.    - This logic involves calling the USDC contract to perform the transfer.    - If the USDC contract is also a proxy (<em>which it is</em>), it will use <code>delegatecall</code> to forward the call to its own implementation contract.</p>
</li>
</ol>
<p>Below is a more detailed look at the transaction as presented on the site 'Tenderly':</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002187925/e7d6735d-f861-4b38-a981-7289fa6d4920.png" alt class="image--center mx-auto" /></p>
<p>Specifically we can see that the <code>fallback</code> function that gets triggered in the WazirX proxy contract is the following:</p>
<pre><code class="lang-solidity"><span class="hljs-comment">/// @dev Fallback function forwards all transactions and returns all received return data.</span>
<span class="hljs-function"><span class="hljs-keyword">fallback</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
    <span class="hljs-comment">// solhint-disable-next-line no-inline-assembly</span>
    <span class="hljs-keyword">assembly</span> {
        <span class="hljs-keyword">let</span> _singleton <span class="hljs-operator">:=</span> <span class="hljs-built_in">and</span>(<span class="hljs-built_in">sload</span>(<span class="hljs-number">0</span>), <span class="hljs-number">0xffffffffffffffffffffffffffffffffffffffff</span>)
        <span class="hljs-comment">// 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s</span>
        <span class="hljs-keyword">if</span> <span class="hljs-built_in">eq</span>(<span class="hljs-built_in">calldataload</span>(<span class="hljs-number">0</span>), <span class="hljs-number">0xa619486e00000000000000000000000000000000000000000000000000000000</span>) {
            <span class="hljs-built_in">mstore</span>(<span class="hljs-number">0</span>, _singleton)
            <span class="hljs-keyword">return</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0x20</span>)
        }
        <span class="hljs-built_in">calldatacopy</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-built_in">calldatasize</span>())
        <span class="hljs-keyword">let</span> success <span class="hljs-operator">:=</span> <span class="hljs-built_in">delegatecall</span>(<span class="hljs-built_in">gas</span>(), _singleton, <span class="hljs-number">0</span>, <span class="hljs-built_in">calldatasize</span>(), <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)
        <span class="hljs-built_in">returndatacopy</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-built_in">returndatasize</span>())
        <span class="hljs-keyword">if</span> <span class="hljs-built_in">eq</span>(success, <span class="hljs-number">0</span>) {
            <span class="hljs-keyword">revert</span>(<span class="hljs-number">0</span>, <span class="hljs-built_in">returndatasize</span>())
        }
        <span class="hljs-keyword">return</span>(<span class="hljs-number">0</span>, <span class="hljs-built_in">returndatasize</span>())
    }
}
</code></pre>
<p>Or as seen below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728002235723/0dc425e6-d08b-4d41-99a6-bddf8e6513e4.png" alt class="image--center mx-auto" /></p>
<p>There are some other functions of interest that we're going to take a look at in the actual exploit analysis. But for now this brief guide should serve as sufficient context for the upgradable proxy smart contract pattern to help provide an understanding for those looking to get a better grasp of how WazirX was compromised.</p>
]]></content:encoded></item><item><title><![CDATA[WazirX Transaction Analysis]]></title><description><![CDATA[Consider some of the following biographical information related to what we're looking at too:

The address of the logic contract / implementation is 0xd9db270c1b5e3bd161e8c8503c55ceabee709552. That contract was created at TX 0x0b04589bdc11585fb98f270...]]></description><link>https://librehash.xyz/wazirx-transaction-analysis</link><guid isPermaLink="true">https://librehash.xyz/wazirx-transaction-analysis</guid><category><![CDATA[hacksa]]></category><category><![CDATA[wazirx]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[smart contract security audit]]></category><category><![CDATA[smart contract audit services]]></category><category><![CDATA[Smart Contract]]></category><category><![CDATA[Smart Contracts]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[hacking]]></category><category><![CDATA[crypto]]></category><category><![CDATA[decentralization]]></category><category><![CDATA[Solidity]]></category><category><![CDATA[EVM]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Thu, 03 Oct 2024 14:47:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727966776384/3388038e-ed11-4729-bab8-932527fa6e0a.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Consider some of the following biographical information related to what we're looking at too:</p>
<ol>
<li><p>The address of the logic contract / implementation is <code>0xd9db270c1b5e3bd161e8c8503c55ceabee709552</code>. That contract was created at TX <code>0x0b04589bdc11585fb98f270b1bfeff0fb3bbb3c56d35b104f62d8115d6f7c57f</code> at block <code>12504268</code>`. This is a smart contract created by Gnosis Safe and used as an implementation proxy address for another smart contract that was exploited by the proxy storage address.</p>
</li>
<li><p>The address for the proxy smart contract address that was compromised was <code>0x27fD43BABfbe83a81d14665b1a6fB8030A60C9b4</code> and that was created by the transaction ID <code>0x3c889ee7c1a19bb15d899f21c5c7d9da0af0c5a5f597f0e288b7309169b4dba5</code> and deployed by <code>0xD7Df5bf3B8d2bd159664dF54A30101d7FAF6cA26</code> by making a call on the smart contract <code>0x4e59b44847b379578588920cA78FbF26c0B4956C</code> to deploy the smart contract address which is labeled as <code>singleton</code>. The address responsible for deploying this contract is <code>0xfA54B4085811aef6ACf47D51B05FdA188DEAe28b</code> at block height <code>16132578</code> and it was deployed from the Gnosis Safe Factory contract located at <code>0xfA54B4085811aef6ACf47D51B05FdA188DEAe28b</code>.</p>
</li>
<li><p>When the smart contract storage proxy address <code>0x27fD43BABfbe83a81d14665b1a6fB8030A60C9b4</code> was created, it established 5 different owners. Those owners are <code>0xaE648f68823bc164CA3ad1f5f5dC0057d9d515aD</code>, <code>0x10F16CdE93f1bC9C38a9e31C8DB0eEb89a744824</code>, <code>0xD83b89E261D02B0f2f9E384B44907f8d380E9AF0</code>, <code>0x9AF78003CecC2383d9D576A49c0C6b17fc34Ae34</code> and <code>0xfA54B4085811aef6ACf47D51B05FdA188DEAe28b</code>. The threshold for this multi-signature address was established as <code>3</code>. The initializer was <code>0x0000000000000000000000000000000000000000</code> and the address for the smart contract designated as the <code>fallbackHandler</code> was <code>0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4</code>. This transaction also designated <code>0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552</code> as the <code>singleton</code> for this address. The singleton is the logic proxy address that we're examining that serves as the main address.</p>
</li>
<li><p>The transaction that ultimately compromised both smart contracts in question occurred at transaction ID: <code>0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d</code>. The sender of the transaction was an EOA with the address <code>0xd967113224c354600b3151e27aaba53e3034f372</code> at block height <code>20331565</code>. The transaction involved a delegatecall being made to the singleton smart contract at <code>0xd9db270c1b5e3bd161e8c8503c55ceabee709552</code> (<em>which is our flattened smart contract</em>) before eventually <code>calldata</code> was forwarded to a malicious smart contract address located at <code>0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2</code>. This EOA (<code>0xd967113224c354600b3151e27aaba53e3034f372</code>)was added as an owner to the <code>0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4</code> smart contract in February 2023 during transaction ID: <code>0xfda0801c5f916fc17d042a8297af15ccdfa91bc12d530fda4708c159e992b19a</code>. The multi-signature threshold was subsequently raised to <code>4</code> afterward.</p>
</li>
</ol>
<p>The source code for all smart contracts involved in the creation of the two proxy smart contracts that I mentioned (<code>0x27fD43BABfbe83a81d14665b1a6fB8030A60C9b4</code> and <code>0xd9db270c1b5e3bd161e8c8503c55ceabee709552</code>) are verified on Etherscan already. Thus, if there is any additional information that is needed then that can be obtained from the blockchain directly.</p>
<p>It is known that none of the keys involved in the multi-signature orchestration were compromised at any point in time and this has been independently verified after the fact. Thus, the flaw, vulnerability or exploit must be laden within the smart contracts themselves. Since the logic within the main proxy (<code>0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4</code>) is nominal at best, we have decided to set our focus on dissecting the <code>singleton</code> contract that was associated with the deployed proxy from Gnosis Safe.</p>
<p>During the malicious transaction we observed that the storage data in slot 0 was updated for the main proxy. This update swapped out the legitimate <code>singleton</code> contract for a malicious one at <code>0xef279c2ab14960aa319008cbea384b9f8ac35fc6</code>. The malicious contract that was responsible for returning data back to the main proxy, resulting in an update of that proxy's <code>singleton</code> address value in <code>slot 0</code> is at the address <code>0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2</code>. The bytecode for both malicious contracts is not verified or available on Etherscan. Therefore, any and all attempts to dissect the true nature of these smart contracts will be contingent on the efficacy of associated bytecode disassemblers.</p>
<p>That transaction <a target="_blank" href="https://etherscan.io/tx/0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d">can be found here</a>. The transaction itself is <strong>highly complex</strong> and reveals a lot of potential issues in the <strong>Safe contract deployment</strong> (yes, those guys formerly known as Gnosis Safe).</p>
<p>Before we make anymore assertions about the nature of the hack, let's go ahead and take a look at the malicious transaction, starting with Etherscan's view.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726857539648/fc1ad404-b8b2-45a3-b339-1b7901abbcce.png" alt class="image--center mx-auto" /></p>
<p>As we can see, it <strong>appears</strong> that the transaction was initiated by the <code>0xd967</code> address - which we've already established as belonging to the team.</p>
<p>The transaction was sent directly to the <code>0x27fD</code> address, which is the WazirX team's <strong>main proxy</strong>. As we've discussed in a (separate guide), the specific proxy upgradable orchestration that WazirX used involves deploying a unique proxy from a "factory contract" (<em>which served as the 'template' for their proxy</em>).</p>
<p>However, the <strong>other associated contracts</strong> (i.e., their <a target="_blank" href="https://etherscan.io/address/0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552">implementation/singleton</a> &amp; <a target="_blank" href="https://etherscan.io/address/0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4">fallback handler</a>) are <strong>Gnosis Safe deployments</strong>. They were never deployed or owned by the team. Thus, any compromise arising out of the functionality of those contracts should also be attributed to the Safe team (<em>more specifically for their failure to make it a widespread imperative for users to upgrade to better constructed implementations</em>).</p>
<p>Getting back to the malicious transaction, let's take a look at the internal transaction trace that the malicious transaction created:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726857565965/75957f9b-cdb9-44d6-a8ed-a0408af8c1b8.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>As we can see abvoe, the entry point was the team's proxy contract with a function call that triggered the contract's</em> <code>fallback</code> <em>function, ultimately leading to a call being delegated to a malicious proxy contract</em> (<a target="_blank" href="https://etherscan.io/address/0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2">0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2</a>)</p>
</blockquote>
<p>Moving forward, let's see if we can't glean more information about the nature of this attack by looking at a simple stack execution trace of the actual compromise.</p>
<p>Check out the parity stack trace below (<em>you can find this on</em> <a target="_blank" href="https://etherscan.io/vmtrace?txhash=0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d&amp;type=parity">Etherscan too</a>):</p>
<pre><code class="lang-json">
  {
    <span class="hljs-attr">"action"</span>: {
      <span class="hljs-attr">"from"</span>: <span class="hljs-string">"0xd967113224c354600b3151e27aaba53e3034f372"</span>,
      <span class="hljs-attr">"callType"</span>: <span class="hljs-string">"call"</span>,
      <span class="hljs-attr">"gas"</span>: <span class="hljs-string">"0x2c9f8"</span>,
      <span class="hljs-attr">"input"</span>: <span class="hljs-string">"0x6a761202000000000000000000000000fbffef83b1c172fe3bc86c1ccb036ab9f3efcaf20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000024804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001043da7c6bd7c130430cf662de3d9af067c4a0629f849e29003c40ad3979cd670720c3ceb3a61e38fb7166353e3262eb6554c3f6571807cf22f9bdc4a83a56441661f8e64a89386af2f223b8433a1df65db8f0ff60544b2f02c56ec02b640d6fb15a11f7dffda5b99b0292b5e02d0cc44508d7d8f994515358e9da3016d8098b2258820000000000000000000000000d967113224c354600b3151e27aaba53e3034f37200000000000000000000000000000000000000000000000000000000000000000140082eba0f71627a3451d47132b8f4c266bc9be2bebe4424848757d10f13e76963af0b543a2357765d9f290410e919301ad065f0f2efa1233eb8634c93111f0e2000000000000000000000000000000000000000000000000000000000"</span>,
      <span class="hljs-attr">"to"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
      <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0"</span>
    },
    <span class="hljs-attr">"blockHash"</span>: <span class="hljs-string">"0xf0716718399afb665776df3378a2bc7c1ff02c03a40af8d6471193b1611b873b"</span>,
    <span class="hljs-attr">"blockNumber"</span>: <span class="hljs-number">20331565</span>,
    <span class="hljs-attr">"result"</span>: {
      <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0xb4eb"</span>,
      <span class="hljs-attr">"output"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000000000000000000000000001"</span>
    },
    <span class="hljs-attr">"subtraces"</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">"traceAddress"</span>: [],
    <span class="hljs-attr">"transactionHash"</span>: <span class="hljs-string">"0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d"</span>,
    <span class="hljs-attr">"transactionPosition"</span>: <span class="hljs-number">21</span>,
    <span class="hljs-attr">"type"</span>: <span class="hljs-string">"call"</span>
  },
  {
    <span class="hljs-attr">"action"</span>: {
      <span class="hljs-attr">"from"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
      <span class="hljs-attr">"callType"</span>: <span class="hljs-string">"delegatecall"</span>,
      <span class="hljs-attr">"gas"</span>: <span class="hljs-string">"0x2abe6"</span>,
      <span class="hljs-attr">"input"</span>: <span class="hljs-string">"0x6a761202000000000000000000000000fbffef83b1c172fe3bc86c1ccb036ab9f3efcaf20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000024804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001043da7c6bd7c130430cf662de3d9af067c4a0629f849e29003c40ad3979cd670720c3ceb3a61e38fb7166353e3262eb6554c3f6571807cf22f9bdc4a83a56441661f8e64a89386af2f223b8433a1df65db8f0ff60544b2f02c56ec02b640d6fb15a11f7dffda5b99b0292b5e02d0cc44508d7d8f994515358e9da3016d8098b2258820000000000000000000000000d967113224c354600b3151e27aaba53e3034f37200000000000000000000000000000000000000000000000000000000000000000140082eba0f71627a3451d47132b8f4c266bc9be2bebe4424848757d10f13e76963af0b543a2357765d9f290410e919301ad065f0f2efa1233eb8634c93111f0e2000000000000000000000000000000000000000000000000000000000"</span>,
      <span class="hljs-attr">"to"</span>: <span class="hljs-string">"0xd9db270c1b5e3bd161e8c8503c55ceabee709552"</span>,
      <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0"</span>
    },
    <span class="hljs-attr">"blockHash"</span>: <span class="hljs-string">"0xf0716718399afb665776df3378a2bc7c1ff02c03a40af8d6471193b1611b873b"</span>,
    <span class="hljs-attr">"blockNumber"</span>: <span class="hljs-number">20331565</span>,
    <span class="hljs-attr">"result"</span>: {
      <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0xa187"</span>,
      <span class="hljs-attr">"output"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000000000000000000000000001"</span>
    },
    <span class="hljs-attr">"subtraces"</span>: <span class="hljs-number">1</span>,
    <span class="hljs-attr">"traceAddress"</span>: [
      <span class="hljs-number">0</span>
    ],
    <span class="hljs-attr">"transactionHash"</span>: <span class="hljs-string">"0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d"</span>,
    <span class="hljs-attr">"transactionPosition"</span>: <span class="hljs-number">21</span>,
    <span class="hljs-attr">"type"</span>: <span class="hljs-string">"call"</span>
  },
  {
    <span class="hljs-attr">"action"</span>: {
      <span class="hljs-attr">"from"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
      <span class="hljs-attr">"callType"</span>: <span class="hljs-string">"delegatecall"</span>,
      <span class="hljs-attr">"gas"</span>: <span class="hljs-string">"0x214ec"</span>,
      <span class="hljs-attr">"input"</span>: <span class="hljs-string">"0x804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc6"</span>,
      <span class="hljs-attr">"to"</span>: <span class="hljs-string">"0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2"</span>,
      <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0"</span>
    },
    <span class="hljs-attr">"blockHash"</span>: <span class="hljs-string">"0xf0716718399afb665776df3378a2bc7c1ff02c03a40af8d6471193b1611b873b"</span>,
    <span class="hljs-attr">"blockNumber"</span>: <span class="hljs-number">20331565</span>,
    <span class="hljs-attr">"result"</span>: {
      <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0xc2e"</span>,
      <span class="hljs-attr">"output"</span>: <span class="hljs-string">"0x"</span>
    },
    <span class="hljs-attr">"subtraces"</span>: <span class="hljs-number">0</span>,
    <span class="hljs-attr">"traceAddress"</span>: [
      <span class="hljs-number">0</span>,
      <span class="hljs-number">0</span>
    ],
    <span class="hljs-attr">"transactionHash"</span>: <span class="hljs-string">"0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d"</span>,
    <span class="hljs-attr">"transactionPosition"</span>: <span class="hljs-number">21</span>,
    <span class="hljs-attr">"type"</span>: <span class="hljs-string">"call"</span>
}
</code></pre>
<blockquote>
<p>Later on, we’re going to go ahead and dissect the bytecode that was sent to the malicious contract and walk through how the opcodes operated on said calldata, step by step to get a better understanding of how this compromise took place.</p>
</blockquote>
<p>While this raw trace (<em>parity</em>) is far from complete in terms of what it does for us, it does provide us with some preliminary information that can begin to give us an understanding of how this hack took place:</p>
<ol>
<li><p>The initial 'action' (i.e., function call) is noted as coming from the <code>0xd967</code> address (<em>more on what this means later and how the hackers could have possibly done this</em>).</p>
</li>
<li><p>That call - which was made to the WazirX main proxy (<code>0x27fd4</code>), triggered the proxy's fallback function, which will always be a <code>delegatecall</code> by default (<em>that's how proxies are designed</em>). For those new to the world of smart contract hacks, compromises, rugpulls etc., this opcode is one of <strong>the most problematic</strong> ones in the entire EVM system.</p>
</li>
<li><p>The first 4 bytes of the <code>calldata</code> tell us what function was being called. If you look back at the <code>json</code> stack execution trace that's printed above, you can identify the <code>calldata</code> as that large hexadecimal value next to the topic called "<strong>input</strong>". If you found it, then you'll notice the first 8 characters (4 bytes) after the <code>0x</code> prefix are <code>6a761202</code>. This hexadecimal value corresponds with the function that was called by the hacker. A quick lookup in a database like <code>4bytes</code> or <a target="_blank" href="http://evm.codes"><code>evm.codes</code></a> reveals that this hexadecimal value corresponds with the function signature <code>execTransaction(address,uint256,bytes,uint8,uint256,uint256uint256,address,address,bytes)</code>.</p>
</li>
<li><p>The <code>calldata</code> that was ultimately sent to the malicious proxy was <code>0x804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc6</code>. There have been some attempts to dissect the meaning of this calldata already in the general public. But thus far, most analyses fall woefully short of breaking down the potency of this short, yet simply crafted <code>calldata</code> value.</p>
</li>
</ol>
<p>What makes this hack so intriguing is its complexity. Despite all we've covered thus far, we've still barely scratched the surface in terms of <strong>how exactly</strong> the threat actor was able to compromise WazirX. But without any further deliberation, let's move forward here. A better breakdown of this transaction is going to require us decompiling the bytecode behind the calldata or piping the transaction itself into a high-quality debugger.</p>
<p>Before we do that, we’re going to need to get a more detailed view of the stack execution trace. This is going to require us going through a debugger similar - either via the terminal or through the use of an online tool that we can use like ‘Tenderly’, ‘Sentio’ or ‘Phalcon’. The latter two of those three online tools are entirely free while Tenderly requires that we at least sign up to obtain a trial subscription (14 days) before payment is necessary. All of them come with their own specific benefits. For those that are not as comfortable with using the terminal, we’re going to go ahead and see</p>
<p>Fortunately, there are plenty of tools in the Ethereum ecosystem that will allow us to do either. And those tools cater to both developers and folks that aren't as comfortable with navigating a terminal. Let's start with the 'terminal' approach.</p>
<p>Before we do that, we’re going to need to get a more detailed view of the stack execution trace. This is going to require us going through a debugger similar - either via the terminal or through the use of an online tool that we can use like ‘Tenderly’, ‘Sentio’ or ‘Phalcon’. The latter two of those three online tools are entirely free while Tenderly requires that we at least sign up to obtain a trial subscription (14 days) before payment is necessary. All of them come with their own specific benefits. Since most users are not quite as well-versed with the terminal, we’re going to go ahead and look at those latter two visual debuggers.</p>
<blockquote>
<p><strong>Disclaimer</strong>: <em>To be clear, the best debugger</em> (in the author's opinion), <em>would be Tenderly since it tends to give us the most accurate decoding of the stack execution trace, step by step. Misinterpretations of some of the steps as well as the sub-steps are what lead to differing outputs as far as the debuggers are concerned</em>.</p>
</blockquote>
<h4 id="heading-sentio-debugger">Sentio Debugger</h4>
<p>For those that have never visited this site, you can find its main interface here: <a target="_blank" href="https://app.sentio.xyz">https://app.sentio.xyz</a>.</p>
<blockquote>
<p><em>They may ask you to signup on the main website. If you want to bypass this step, just go ahead and visit this link here</em>: <a target="_blank" href="https://app.sentio.xyz/tx/1/0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d?t=1&amp;block=0x131fe81">https://app.sentio.xyz/tx/1/0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d?t=1&amp;block=0x131fe81</a> ; <em>this will take you directly to the malicious transaction in question without being forced to sign-up or login to the website</em>.</p>
</blockquote>
<p>Once you arrive at the panel for the malicious transaction, you should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727930923438/17f72253-4c6d-48e1-a5c8-985e11d9bad3.png" alt class="image--center mx-auto" /></p>
<p>From here, we're going to take a look at some of the panels at the bottom, which go by the names of <code>Call Trace</code>, <code>Call Graph</code> and <code>Gas Profiler</code> (<em>we're not quite as interested in the last tab, but we may take a breeze through it for good measure</em>).</p>
<p><strong>Call Trace Panel</strong></p>
<blockquote>
<p><em>If you're not used to looking at transaction traces, this may be a bit overwhelming at first, but don't worry - we'll make ourselves familiar with the context shortly</em></p>
</blockquote>
<p>Upon firs visiting the <code>Call Trace</code> panel on the Sentio site for the malicious transaction, we should see the following at the bottom half of the page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727930946794/b9558e4c-184e-4f72-96c4-4f487f045093.png" alt class="image--center mx-auto" /></p>
<p>Its worth noting that definition for a 'Stack Call Trace' given in the top right corner of our screenshot above. Specifically, it states, "<em>In a smart contract transaction, a static call (also known as a view or constant call) is a read-only operation that retrieves data from the blockchain without modifying any state. This means that a static call does not change the state of the blockchain or of the smart contract being called.</em>"</p>
<p>That's how we're able to get that stack execution trace that we see below (<em>keep in mind, this still isn't the debugged version of the transaction</em>). Some of the data here won't be entirely accurate and there are also some parts of the data that we need to further decode in order to get the "decoded" version.</p>
<h4 id="heading-tenderly-debugged-transaction">Tenderly Debugged Transaction</h4>
<blockquote>
<p><em>Tenderly is probably the best platform to use if you want to not only get a thorough transaction trace but a fully debugged, stepped re-simulation of the transaction itself as well</em></p>
</blockquote>
<p>Assuming you've already signed up for an account on <a target="_blank" href="https://app.tenderly.co">Tenderly</a> (<em>they provide a free trial for new users for 14 days before restricting some features</em>), this will be our best source for debugging the full transaction trace.</p>
<p>We're going to proceed forth with a free account for the sake of brevity (<em>sorry, Tenderly, we're on a budget - but if you'd like to throw a free membership, that would be greatly appreciated!</em>).</p>
<blockquote>
<p><em>Seriously though, if you got the chance, make sure you go ahead and grab a Tenderly subscription / membership if you need to do anything even peripherally related to these activities in the blockchain space</em>.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931003536/c467f66b-fd43-4c94-a45a-4086496ec871.png" alt class="image--center mx-auto" /></p>
<p>Once we're at the dashboard, we can go setup a virtual testnet, which will be based on a fork of the target network (Ethereum) at its current height (at the time of writing), which is well beyond the time of the hack. Don't worry though, if we need to revert the state of the blockchain to an earlier point in time, we'll be able to do so without any issue (<em>you'll understand why this was mentioned later on</em>).</p>
<p>First, we're going to add some of the relevant contracts to our dashboard. See the truncated list of contracts we're going to provide below:</p>
<ul>
<li><p><code>0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4</code> (WazirX main proxy contract)</p>
</li>
<li><p><code>0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552</code> (Logic Contract/Singleton for the Main Proxy)</p>
</li>
<li><p><code>0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4</code> (Fallback Handler for the Contract)</p>
</li>
<li><p><code>0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2</code> (this is the attacker contract that was involved in the OG malicious transaction that ultimately compromised the WazirX main proxy contract)</p>
</li>
</ul>
<blockquote>
<p><em>If you're feeling ambitious/productive, then you can go ahead and hunt down the factory contracts that some of the proxies were deployed from as well as the contracts responsible for the deployment</em> (where this is applicable)</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931026666/00b4d08a-38dc-4b1a-b9ac-c3d03b8e81f0.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931035358/50071544-34af-4553-83b4-e5e4c0524618.png" alt class="image--center mx-auto" /></p>
<p>Now that we have the contracts added, let's take a renewed look at the stack execution trace for the main hack that occurred.</p>
<p>This requires having an RPC endpoint that we can query to get the full trace of the transaction. Since we have Tenderly, that's not an issue. On the lefthand side on the panel menu, there's an option that reads, 'Node RPCs'.</p>
<p>If we select that option, then we'll see an option to <code>Create Node</code>. Once we click on that, we just navigate through the interface and then select the appropriate options.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931139383/007102d5-c7f3-4691-a3be-4081eb88c83c.png" alt class="image--center mx-auto" /></p>
<p>Once a node is created, users are taken to the following 'home screen' for their personal node (RPC endpoint).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931198049/66b06e63-e59c-4741-ae74-2871cf23ae48.png" alt class="image--center mx-auto" /></p>
<p>On the lefthand side of the panel, we can see an option called 'RPC Builder'. We're going to select that option and then pull up the following screen.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931228704/97e0cd23-49bc-4bed-8e76-71154b6fb61a.png" alt class="image--center mx-auto" /></p>
<p>From here, we're going to select an RPC option called <code>tenderly_traceTransaction</code>. Its stated that this RPC call, "<em>Replays transaction on the blockchain and provides information about the execution, such as status, logs, internal transactions, etc.</em>"</p>
<p>For those not as savvy with the terminal, all that one needs to do is edit the <code>params</code> key with the value of whatever transaction ID they're looking to receive a stack execution trace for (<em>which in this case is</em> <a target="_blank" href="https://etherscan.io/tx/0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d">0x48164d3adbab78c2cb9876f6e17f88e321097fcd14cadd57556866e4ef3e185d</a>).</p>
<p>If done correctly, your screen should look as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727931250715/394c20dd-bbb6-44d1-93fe-7e8a823e5d6e.png" alt class="image--center mx-auto" /></p>
<p>When we click the 'Run' button located at the top right, then we'll receive the full, detailed trace.</p>
<p>That trace should look like the following:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-number">0</span>,
  <span class="hljs-attr">"jsonrpc"</span>: <span class="hljs-string">"2.0"</span>,
  <span class="hljs-attr">"result"</span>: {
    <span class="hljs-attr">"status"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0x11f43"</span>,
    <span class="hljs-attr">"cumulativeGasUsed"</span>: <span class="hljs-string">"0x11f43"</span>,
    <span class="hljs-attr">"blockNumber"</span>: <span class="hljs-string">"0x1363c2d"</span>,
    <span class="hljs-attr">"type"</span>: <span class="hljs-string">"0x2"</span>,
    <span class="hljs-attr">"logsBloom"</span>: <span class="hljs-string">"0x00000000400000000000000000000000000000000000000000000000040000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"</span>,
    <span class="hljs-attr">"logs"</span>: [
      {
        <span class="hljs-attr">"name"</span>: <span class="hljs-string">"ExecutionSuccess"</span>,
        <span class="hljs-attr">"anonymous"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">"inputs"</span>: [
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x4e82121a3bc2fb62c0b06ab5fff5ca965ceab4f51cc949c6e50d85ed63e6aa70"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bytes32"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"txHash"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"payment"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          }
        ],
        <span class="hljs-attr">"raw"</span>: {
          <span class="hljs-attr">"address"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
          <span class="hljs-attr">"topics"</span>: [
            <span class="hljs-string">"0x442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e"</span>
          ],
          <span class="hljs-attr">"data"</span>: <span class="hljs-string">"0x4e82121a3bc2fb62c0b06ab5fff5ca965ceab4f51cc949c6e50d85ed63e6aa700000000000000000000000000000000000000000000000000000000000000000"</span>
        }
      }
    ],
    <span class="hljs-attr">"trace"</span>: [
      {
        <span class="hljs-attr">"type"</span>: <span class="hljs-string">"CALL"</span>,
        <span class="hljs-attr">"from"</span>: <span class="hljs-string">"0xd967113224c354600b3151e27aaba53e3034f372"</span>,
        <span class="hljs-attr">"to"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
        <span class="hljs-attr">"gas"</span>: <span class="hljs-string">"0x2c9f8"</span>,
        <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0xb4eb"</span>,
        <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0"</span>,
        <span class="hljs-attr">"input"</span>: <span class="hljs-string">"0x6a761202000000000000000000000000fbffef83b1c172fe3bc86c1ccb036ab9f3efcaf20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000024804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001043da7c6bd7c130430cf662de3d9af067c4a0629f849e29003c40ad3979cd670720c3ceb3a61e38fb7166353e3262eb6554c3f6571807cf22f9bdc4a83a56441661f8e64a89386af2f223b8433a1df65db8f0ff60544b2f02c56ec02b640d6fb15a11f7dffda5b99b0292b5e02d0cc44508d7d8f994515358e9da3016d8098b2258820000000000000000000000000d967113224c354600b3151e27aaba53e3034f37200000000000000000000000000000000000000000000000000000000000000000140082eba0f71627a3451d47132b8f4c266bc9be2bebe4424848757d10f13e76963af0b543a2357765d9f290410e919301ad065f0f2efa1233eb8634c93111f0e2000000000000000000000000000000000000000000000000000000000"</span>,
        <span class="hljs-attr">"decodedInput"</span>: [
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"to"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"value"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc6"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bytes"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"data"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint8"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"operation"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"safeTxGas"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"baseGas"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"gasPrice"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"gasToken"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"refundReceiver"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x3da7c6bd7c130430cf662de3d9af067c4a0629f849e29003c40ad3979cd670720c3ceb3a61e38fb7166353e3262eb6554c3f6571807cf22f9bdc4a83a56441661f8e64a89386af2f223b8433a1df65db8f0ff60544b2f02c56ec02b640d6fb15a11f7dffda5b99b0292b5e02d0cc44508d7d8f994515358e9da3016d8098b2258820000000000000000000000000d967113224c354600b3151e27aaba53e3034f37200000000000000000000000000000000000000000000000000000000000000000140082eba0f71627a3451d47132b8f4c266bc9be2bebe4424848757d10f13e76963af0b543a2357765d9f290410e919301ad065f0f2efa1233eb8634c93111f0e20"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bytes"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"signatures"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          }
        ],
        <span class="hljs-attr">"output"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000000000000000000000000001"</span>,
        <span class="hljs-attr">"decodedOutput"</span>: [
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bool"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"success"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          }
        ],
        <span class="hljs-attr">"subtraces"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-attr">"traceAddress"</span>: []
      },
      {
        <span class="hljs-attr">"type"</span>: <span class="hljs-string">"DELEGATECALL"</span>,
        <span class="hljs-attr">"from"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
        <span class="hljs-attr">"to"</span>: <span class="hljs-string">"0xd9db270c1b5e3bd161e8c8503c55ceabee709552"</span>,
        <span class="hljs-attr">"gas"</span>: <span class="hljs-string">"0x2abe6"</span>,
        <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0xa187"</span>,
        <span class="hljs-attr">"input"</span>: <span class="hljs-string">"0x6a761202000000000000000000000000fbffef83b1c172fe3bc86c1ccb036ab9f3efcaf20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000024804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001043da7c6bd7c130430cf662de3d9af067c4a0629f849e29003c40ad3979cd670720c3ceb3a61e38fb7166353e3262eb6554c3f6571807cf22f9bdc4a83a56441661f8e64a89386af2f223b8433a1df65db8f0ff60544b2f02c56ec02b640d6fb15a11f7dffda5b99b0292b5e02d0cc44508d7d8f994515358e9da3016d8098b2258820000000000000000000000000d967113224c354600b3151e27aaba53e3034f37200000000000000000000000000000000000000000000000000000000000000000140082eba0f71627a3451d47132b8f4c266bc9be2bebe4424848757d10f13e76963af0b543a2357765d9f290410e919301ad065f0f2efa1233eb8634c93111f0e2000000000000000000000000000000000000000000000000000000000"</span>,
        <span class="hljs-attr">"decodedInput"</span>: [
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"to"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"value"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc6"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bytes"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"data"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint8"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"operation"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"safeTxGas"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"baseGas"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"uint256"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"gasPrice"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"gasToken"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"address"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"refundReceiver"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          },
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-string">"0x3da7c6bd7c130430cf662de3d9af067c4a0629f849e29003c40ad3979cd670720c3ceb3a61e38fb7166353e3262eb6554c3f6571807cf22f9bdc4a83a56441661f8e64a89386af2f223b8433a1df65db8f0ff60544b2f02c56ec02b640d6fb15a11f7dffda5b99b0292b5e02d0cc44508d7d8f994515358e9da3016d8098b2258820000000000000000000000000d967113224c354600b3151e27aaba53e3034f37200000000000000000000000000000000000000000000000000000000000000000140082eba0f71627a3451d47132b8f4c266bc9be2bebe4424848757d10f13e76963af0b543a2357765d9f290410e919301ad065f0f2efa1233eb8634c93111f0e20"</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bytes"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"signatures"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          }
        ],
        <span class="hljs-attr">"method"</span>: <span class="hljs-string">"execTransaction"</span>,
        <span class="hljs-attr">"output"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000000000000000000000000001"</span>,
        <span class="hljs-attr">"decodedOutput"</span>: [
          {
            <span class="hljs-attr">"value"</span>: <span class="hljs-literal">true</span>,
            <span class="hljs-attr">"type"</span>: <span class="hljs-string">"bool"</span>,
            <span class="hljs-attr">"name"</span>: <span class="hljs-string">"success"</span>,
            <span class="hljs-attr">"indexed"</span>: <span class="hljs-literal">false</span>
          }
        ],
        <span class="hljs-attr">"subtraces"</span>: <span class="hljs-number">1</span>,
        <span class="hljs-attr">"traceAddress"</span>: [
          <span class="hljs-number">0</span>
        ]
      },
      {
        <span class="hljs-attr">"type"</span>: <span class="hljs-string">"DELEGATECALL"</span>,
        <span class="hljs-attr">"from"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
        <span class="hljs-attr">"to"</span>: <span class="hljs-string">"0xfbffef83b1c172fe3bc86c1ccb036ab9f3efcaf2"</span>,
        <span class="hljs-attr">"gas"</span>: <span class="hljs-string">"0x214ec"</span>,
        <span class="hljs-attr">"gasUsed"</span>: <span class="hljs-string">"0xc2e"</span>,
        <span class="hljs-attr">"input"</span>: <span class="hljs-string">"0x804e1f0a000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc6"</span>,
        <span class="hljs-attr">"output"</span>: <span class="hljs-string">"0x"</span>,
        <span class="hljs-attr">"subtraces"</span>: <span class="hljs-number">0</span>,
        <span class="hljs-attr">"traceAddress"</span>: [
          <span class="hljs-number">0</span>,
          <span class="hljs-number">0</span>
        ]
      }
    ],
    <span class="hljs-attr">"stateChanges"</span>: [
      {
        <span class="hljs-attr">"address"</span>: <span class="hljs-string">"0x27fd43babfbe83a81d14665b1a6fb8030a60c9b4"</span>,
        <span class="hljs-attr">"storage"</span>: [
          {
            <span class="hljs-attr">"slot"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000000000000000000000000000"</span>,
            <span class="hljs-attr">"previousValue"</span>: <span class="hljs-string">"0x000000000000000000000000d9db270c1b5e3bd161e8c8503c55ceabee709552"</span>,
            <span class="hljs-attr">"newValue"</span>: <span class="hljs-string">"0x000000000000000000000000ef279c2ab14960aa319008cbea384b9f8ac35fc6"</span>
          },
          {
            <span class="hljs-attr">"slot"</span>: <span class="hljs-string">"0x0000000000000000000000000000000000000000000000000000000000000005"</span>,
            <span class="hljs-attr">"previousValue"</span>: <span class="hljs-string">"0x00000000000000000000000000000000000000000000000000000000000006b6"</span>,
            <span class="hljs-attr">"newValue"</span>: <span class="hljs-string">"0x00000000000000000000000000000000000000000000000000000000000006b7"</span>
          }
        ]
      },
      {
        <span class="hljs-attr">"address"</span>: <span class="hljs-string">"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5"</span>,
        <span class="hljs-attr">"balance"</span>: {
          <span class="hljs-attr">"previousValue"</span>: <span class="hljs-string">"0xfd1064e88789a744"</span>,
          <span class="hljs-attr">"newValue"</span>: <span class="hljs-string">"0xfd11419f913eea44"</span>
        }
      },
      {
        <span class="hljs-attr">"address"</span>: <span class="hljs-string">"0xd967113224c354600b3151e27aaba53e3034f372"</span>,
        <span class="hljs-attr">"nonce"</span>: {
          <span class="hljs-attr">"previousValue"</span>: <span class="hljs-string">"0xb9c"</span>,
          <span class="hljs-attr">"newValue"</span>: <span class="hljs-string">"0xb9d"</span>
        },
        <span class="hljs-attr">"balance"</span>: {
          <span class="hljs-attr">"previousValue"</span>: <span class="hljs-string">"0xab9e0a1fde78eca"</span>,
          <span class="hljs-attr">"newValue"</span>: <span class="hljs-string">"0xab777e165b284d3"</span>
        }
      }
    ]
  }
}
</code></pre>
<p>Now that we have this full stack execution trace, we can properly assess what exactly happened here on a more thorough basis.</p>
]]></content:encoded></item><item><title><![CDATA[WazirX Background Information]]></title><description><![CDATA[WazirX is an cryptocurrency exchange primarily based in India with an ambiguous origin story that ties to the now-infamous Binance exchange (see: ChangpengZhao prison sentence). If you're interested to learn more about the connection between Binance ...]]></description><link>https://librehash.xyz/wazirx-background-information</link><guid isPermaLink="true">https://librehash.xyz/wazirx-background-information</guid><category><![CDATA[wazirx]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto exchange]]></category><category><![CDATA[exploit]]></category><category><![CDATA[hacking]]></category><category><![CDATA[vulnerability]]></category><category><![CDATA[smart contract security]]></category><category><![CDATA[smart contract development]]></category><category><![CDATA[Smart Contract]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[altcoin]]></category><category><![CDATA[safe]]></category><category><![CDATA[gnosis]]></category><category><![CDATA[cryptocurrency exchange]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 20 Sep 2024 02:10:22 GMT</pubDate><content:encoded><![CDATA[<p>WazirX is an cryptocurrency exchange primarily based in India with an ambiguous origin story that ties to the now-infamous Binance exchange (<strong>see</strong>: ChangpengZhao prison sentence). If you're interested to learn more about the connection between Binance and WazirX, feel free to use Google, Twitter, CoinTelegraph or any other resource that you consider to be a reliable dispenser of truth because this analysis is purely technical.</p>
<p>Any additional banal / circumstantial information that gets included in this write-up will be done purely for informational purposes to enhance the reader's overall understanding of the exploit that occurred last month (July 18th) that drained ~$230 million worth of cryptocurrency from WazirX's smart contract orchestration.</p>
<h3 id="heading-how-did-wazirx-store-their-users-funds">How Did WazirX Store Their User's Funds?</h3>
<p>Without wasting any time, we're going to get right down to business here and explore exactly how WazirX was holding/managing user funds from both a fundamental and technical perspective.</p>
<p><strong>How Can This be Both Technical &amp; Fundamental?</strong></p>
<blockquote>
<p><em>We can glean certain information about the custodial practices of WazirX by simply analyzing the related smart contracts in their orchestration as well as associated on-chain data. However, our understanding will also be supplemented by additional information given to us through WazirX's public communications following the hack</em> (i.e., Liminal being a 3rd-party custodian with a unique key whose signatures contributed to the multi-signature threshold necessary to confirm transactions or how the keys that were responsible for signing in WazirX's possession were managed in a mutually independent manner among the team members).</p>
</blockquote>
<p>Before we begin dissecting the actual smart contract orchestration and security protocol implemented by WazirX to ensure the safe custody of their user's funds, <strong>this analysis declares</strong> (<em>and hopefully debunks</em>) <strong>the following proposed "possibilities" to be unequivocally false</strong>:</p>
<ol>
<li><p><strong>The Hack Was an Inside Job</strong> - <em>This analysis unequivocally rejects the notion that this hack was an inside job due to its complexity, lack of apparent motive on the part of the exchange owners</em> (apart from the obvious $230 million), <em>as well as efforts made on their part post-hack to rectify the situation</em> (whether these attempts have gained favor with the exchange's customers or not). <em>At face value, we've never seen an 'exit scam' perpetuated in the manner WazirX was deprived of $230 million of its customer funds. Also, the assumed post-hack consultation with India's relevant governance and police authorities, cash-bounty reward offer and divulgence of intimate details of the exchange's security protocol for handling the custody of user funds lends additional credence to the notion that this was not an inside job. Additionally, the hack that was executed was so complex in nature, its</em> (respectfully) <em>questionable whether anyone on WazirX's team possesses the capability of orchestrating such a heist. As we dig into the minutiae of this compromise, that statement I made in the prior sentence will be understood on an increasingly greater level.</em></p>
</li>
<li><p><strong>The Team / Liminal Mishandled Their Keys</strong> - <em>Another theory that's floated around is that the team mishandled their keys in some way. Although it seems that there are few proponents of this theory on social media and elsewhere at this point in time. Also, WazirX recently published a press release on their site affirming that they each 'signer' responsible for authorizing transactions on the Ethereum blockchain on WazirX's team had their devices independently audited by a cybersecurity firm</em> (Mandiant), <em>whom certified that no team member's device was compromised at or before the time of the actual theft of customer funds from the exchange's Ethereum smart contract orchestration.</em></p>
</li>
<li><p><strong>The Team SIgned a 'Bad' Transaction</strong> - <em>This is one of the most popular</em> (if not prevailing) <em>theories out right now. Essentially, this theory asserts that a bad actor crafted a malicious transaction which included additional / erroneous data and submitted it to the WazirX exchange to be signed. As the theory goes, the team - unbeknownst to them - ended up signing the malicious transaction, inadvertently granting ownership-level privileges or authorization to the bad actor that crafted the transaction. This allowed the bad actor to gain illicit authorization over WazirX's smart contract orchestration, fulfilling a critical pre-requisite for the hack and subsequent appropriation of user funds. The issue with this theory is that</em> <strong>it is entirely unsupported by on-chain data</strong>. <em>After careful examination of several dozen or hundred transactions leading up to the hack, associated emitted events &amp; function calls and the mandated dynamic/static fields encapsulated within those function signatures in the ultimate signed transaction, there is no credence to the idea that the team was bamboozled with a maliciously crafted transaction that simply snuck by under their noses.</em> <em>This rejection also extends to the notion that the team visited a site with malicious javascript embedded within that triggered a signature authorization workflow that they were tricked into signing</em> (whether by virtue of effective 'phishing' or otherwise).</p>
</li>
</ol>
<p>If we take a closer look at the contract deployments by the WazirX team, we'll see that the contracts in which they were in contact with were either deployed or owned by the Safe team itself.</p>
<p>This is evidenced <a target="_blank" href="https://docs.safe.global/advanced/smart-account-supported-networks/v1.3.0">on their site here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797680240/b5b127bc-7da2-46aa-8436-38efcba78d59.png" alt class="image--center mx-auto" /></p>
<p>The screenshot above comes directly from the Safe website (linked above). On their site, at the top of that page they state that, "<em>this page lists all of the safe contracts</em> <code>v1.3.0</code>." Notably, there are 3 contracts that we highlighted here.</p>
<p>Those contracts are:</p>
<ul>
<li><p><a target="_blank" href="https://etherscan.io/address/0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4">0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4</a></p>
</li>
<li><p><a target="_blank" href="https://etherscan.io/address/0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552">0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552</a></p>
</li>
<li><p><a target="_blank" href="https://etherscan.io/address/0x3E5c63644E683549055b9Be8653de26E0B4CD36E">0x3E5c63644E683549055b9Be8653de26E0B4CD36E</a></p>
</li>
</ul>
<p>For those that have been following the hack to some extent, you'll likely recognize at least two of those three contracts. The first one (<code>0xf48</code>), is the designated fallback handler for the WazirX main proxy (<code>0x27</code>). The second one is the implementation proxy (<code>0xd9Db</code>) associated with their main proxy (<code>0x27</code>).</p>
<h3 id="heading-studying-the-creation-of-the-wazirx-proxy-contract-address">Studying the Creation of the WazirX Proxy Contract Address</h3>
<p>Let's begin by reviewing the transaction that led to the creation of the initial WazirX proxy in the first place. That transaction <a target="_blank" href="https://etherscan.io/tx/0x3c889ee7c1a19bb15d899f21c5c7d9da0af0c5a5f597f0e288b7309169b4dba5">can be found here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797755840/1038f0b3-d970-41ae-a8c7-fa4aecc92daf.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>For more technically inclined readers or those well-versed with deciphering Ethereum/EVM-based transactions, I included the full transaction trace</em> <a target="_blank" href="https://gist.github.com/Librechain/776166460522019a021a78539b82271c">here</a> <em>in a gist</em>. [credit to Tenderly for providing the RPC to pull the TX trace from]</p>
</blockquote>
<p>If we check out the <code>logs</code> panel on Etherscan, we'll see a lot of relevant information displayed there for us that we're going to come back and reference shortly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797773070/92980f02-699d-41df-ac88-cdd550e76c5f.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797778672/d1542cae-dd97-4bdb-806c-6d95ef292a5a.png" alt class="image--center mx-auto" /></p>
<p>Just in case you didn't catch it in the screenshots above, here's what you need to know.</p>
<p>The <strong>designated owners of this contract</strong> from its inception were/are:</p>
<ul>
<li><p>0xfA54B4085811aef6ACf47D51B05FdA188DEAe28b</p>
</li>
<li><p>0x9AF78003CecC2383d9D576A49c0C6b17fc34Ae34</p>
</li>
<li><p>0xD83b89E261D02B0f2f9E384B44907f8d380E9AF0</p>
</li>
<li><p>0x10F16CdE93f1bC9C38a9e31C8DB0eEb89a744824</p>
</li>
<li><p>0xaE648f68823bc164CA3ad1f5f5dC0057d9d515aD The <strong>fallback handler</strong> for this contract is: <a target="_blank" href="https://etherscan.io/address/0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4">0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4</a> The <strong>singleton</strong> (implementation proxy) <strong>is</strong>: <a target="_blank" href="https://etherscan.io/address/0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552">0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552</a> The <strong>main proxy</strong> (unique) <strong>that was created from this transaction was</strong>: <a target="_blank" href="https://etherscan.io/address/0x27fD43BABfbe83a81d14665b1a6fB8030A60C9b4">0x27fD43BABfbe83a81d14665b1a6fB8030A60C9b4</a></p>
</li>
</ul>
<p>That proxy address is the smart contract known as 'WazirX 2' on Etherscan and is the infamous address associated with the ~$230 million theft of funds from the exchange. The transaction that we just looked at took place on December 7th, 2022.</p>
<p>If we fast forward just a few short months later, we can see that there was another owner added to the contract and the threshold for the multi-signatures was adjusted upward from '3' to '4'.</p>
<p>That transaction <a target="_blank" href="https://etherscan.io/tx/0xfda0801c5f916fc17d042a8297af15ccdfa91bc12d530fda4708c159e992b19a">can be found here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797813651/2deeabe6-d4fd-4ce7-b677-cfd14f8847d5.png" alt class="image--center mx-auto" /></p>
<p>Worthy of note here is the fact that the transaction was initiated by an account that was already designated as one of the original owners of the WazirX main proxy implementation (<code>0x27fD</code>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797825887/841cdc17-f2ed-44f4-b2e6-db94f30415ce.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797830244/202f8c71-89ef-4a9e-9cd9-c3ca1d3d3f4b.png" alt class="image--center mx-auto" /></p>
<p>Heading to the transaction logs, we can see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797840170/abb8b34c-a4d9-4db0-8086-71786992245b.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>The</em> <code>0xd9671</code> <em>EOA</em> (external owned account; not a smart contract), <em>addition as an owner occurred simultaneously with the increase in the smart contract's multi-signature threshold from</em> <strong>3</strong> <em>to</em> <strong>4</strong>.</p>
</blockquote>
<p>At the time of writing (nearly a month and a half after the attack), the team has yet to state that this was an erroneous or malicious addition. The idea that the transaction was legitimate is even further reinforced by the fact that said transaction was brought to the attention of the exchange on social media by a user named 'TruthLabs' <a target="_blank" href="https://x.com/BoringSleuth/status/1819145014368522410">here</a>.</p>
<p>Curiously, the exchange provided a response to the thread that this user posted that acknowledged the multi-signature structure of the wallet (<em>specifically the requirement that there be 4 signers for each transaction; a fact only made true by the same transaction that added the</em> <code>0xd9671</code> <em>smart contract address</em>).</p>
<p>The exchange's response <a target="_blank" href="https://x.com/WazirXIndia/status/1819298236005523585">can be found here</a> (also their response and the entire thread has been <a target="_blank" href="https://archive.ph/wip/6hS17">archived permanently here</a>).</p>
<p>That response is re-posted below for convenience:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797872619/5fefa942-ad8c-4454-b8d2-549ad29754cb.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Of note is the exchange's declaration that</em> "While any <strong>4 keys</strong> are needed, ever since we moved to Liminal, it has always been 3 separate WazirX key holders and 1 Liminal signing all of the transactions on the ETH wallet that was attacked. Even the malicious transaction that led to the attack was signed by 3 separate WazirX signers and 1 Liminal signer and this data is provable from the signatures made on those transactions."</p>
</blockquote>
<h4 id="heading-why-this-is-worth-mentioning">Why This is Worth Mentioning</h4>
<p>For some reason, certain block explorers have decided to label the <code>0xd967</code> address as the exploiter itself. But this is grossly inaccurate.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726797927664/d91ebd80-dd31-47be-9bcc-b3f88de77a7c.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>The screenshot above is from the Phalcon block explorer. They decided to label this address as 'WazirX exploiter' for some erroneous reason</em>.</p>
</blockquote>
<p>To understand how the compromise took place, we need to operate off of a few assumptions first:</p>
<ul>
<li><p>None of the keys in the multi-signature setup that the team had were compromised at any point in time.</p>
</li>
<li><p>We must examine the smart contract(s) associated with WazirX's proxy upgradable deployment to gain a true understanding of what happened here.</p>
</li>
<li><p>This attack was <strong>not an inside job</strong>. Although, we can never rule this out entirely - the complexity of this hack <strong>strongly suggests</strong> that some outside group or threat actor was responsible for compromising WazirX. Many have suggested that the North Korean threat actor group 'Lazarus' was responsible. This is plausible, if not likely when considering the <strong>nature</strong> of the attack (i.e., <em>how it was orchestrated</em>).</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Bitcoin Price Analysis (September 18th, 2024)]]></title><description><![CDATA[Its been a long time since we've done a Bitcoin price analysis. But figured that there's no time better than the present for us to explore exactly what the fuck is going on as it pertains to Bitcoin. First, we're going to look at the overall price ac...]]></description><link>https://librehash.xyz/bitcoin-price-analysis-september-18th-2024</link><guid isPermaLink="true">https://librehash.xyz/bitcoin-price-analysis-september-18th-2024</guid><category><![CDATA[Bitcoin]]></category><category><![CDATA[BTC]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Price Analysis]]></category><category><![CDATA[Price]]></category><category><![CDATA[Technical Analysis]]></category><category><![CDATA[Ethereum]]></category><category><![CDATA[Altcoins]]></category><category><![CDATA[altcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Thu, 19 Sep 2024 04:43:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726720550566/4ff94f50-add4-42a9-b083-846a575b70de.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Its been a <strong>long time</strong> since we've done a Bitcoin price analysis. But figured that there's no time better than the present for us to explore exactly what the fuck is going on as it pertains to Bitcoin. First, we're going to look at the overall price action and then move from there.</p>
<h2 id="heading-daily-resolution">Daily Resolution</h2>
<p>We're going to start with the daily resolution like we usually do to get an idea of what's going to happen in the not-so-distant future.</p>
<p>Since this is our time charting in a little while, let's establish a few status quos.</p>
<ol>
<li><p>We're going with the 'Coinbase' chart for BTC/USD.</p>
</li>
<li><p>We're starting on the daily resolution (which means that we're looking at the 1-day chart; every candle = 1 day's worth of price data).</p>
</li>
</ol>
<p>Beyond that, we're going to our chart mode to 'logarithmic'. We do that by first right-clicking on the price scale presented on the righthand side of our chart (<em>where it gives us the price of our asset</em>). Doing so, will pop up a context menu specific to this web app. In that context menu, we're going to tick the option that reads 'logarithmic'.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718226716/4d556e4f-b8bb-49a1-8879-640a204cae40.png" alt class="image--center mx-auto" /></p>
<p><strong>Purpose of Changing Our Chart Mode to Logarithmic</strong></p>
<p>Our first step in charting any asset is to plot the resistance and support points. Some of those areas will require us to draw diagonal lines connecting various low's or high's in the price data that span back a few days, months or possibly even years in some cases.</p>
<p>Given Bitcoin's volatile price action at various points in time, it is more than likely that we'll capture price data in this span that's a substantial distance from the current price. If we stick with Bitcoin, for example, the price is ~$56,000 at the time of writing. However, just a few months prior on January 23rd, 2024, Bitcoin was floating around ~$39,000.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726716528852/9fe0dc65-9bdd-43bd-ac07-89927e2b5110.png" alt class="image--center mx-auto" /></p>
<p>In less than two months from that point, the price spiked all the way up to ~$73k, representing an +88.25% increase.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726716553996/1197dff8-feb8-430a-a54e-18e14d2a68eb.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-resistance-and-support-points">Resistance and Support Points</h3>
<p>We're going to start by applying the overhead diagonal resistance to the price action. As we'll see below, this resistance spans all the way back to June 2024 on our daily resolution.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726716568650/6cb0811a-4be8-4687-976a-b7f02acdefde.png" alt class="image--center mx-auto" /></p>
<p>From here, we're going to plot the underlying support at $54k.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726716638836/70dcbb17-35d3-4588-85fb-3af2122483a0.png" alt class="image--center mx-auto" /></p>
<p><strong>Some Initial Takeaways</strong></p>
<p>We can see that the price of Bitcoin is currently in a descending triangle, which is a <strong>bearish pattern</strong>. So that's one negative for the bulls already out the gate. Also, the overhead diagonal resistance that we plotted has been firmly established via two additional touches, reinforcing the strength of this overhead resistance.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726716658109/f934060d-bf0d-4e77-a337-472695e498d7.png" alt class="image--center mx-auto" /></p>
<p>So for those that are wondering whether Bitcoin's price action appears "bearish" or "bullish", the answer is definitively bearish if we're to judge from how the price has reacted to various support and resistance points on the daily resolution.</p>
<h3 id="heading-update-on-the-descending-triangle"><strong>Update on the Descending Triangle</strong></h3>
<p>Its been a few days since those initial screenshots were taken. With that in consideration, let's go take a look at Bitcoin's price action relative to those resistance points that we identified above as well as the descending triangle pattern that we identified.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718602198/b0b7f5db-0b59-424f-9331-ae0709b54e2f.png" alt class="image--center mx-auto" /></p>
<p>As we can see in the chart above, Bitcoin's price action is moving as expected. At the time of writing, it appears that the price is on a crash course toward are overhead diagonal resistance that we juste plotted. (forming one of the legs of our descending triangle pattern).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718626519/8b4e4ae8-0590-4ef1-8679-38d8c941d883.png" alt class="image--center mx-auto" /></p>
<p>Based on the descending triangle chart pattern and general knowledge when it comes to resistance and support points, it only makes sense that we'd expect Bitcoin's price to retreat after hitting this diagonal overhead resistance.</p>
<p>However, nothing is a guarantee and patterns are broken all the time in the world of trading. So let's see what some of the other indicators are telling us.</p>
<h2 id="heading-overlay-chat-indicators">Overlay Chat Indicators</h2>
<p>Now we're going to take a look at some custom overlay indicators as well as some classic/traditional ones to get a better sense of the overall sentiment for Bitcoin in both the short and long-term.</p>
<p>If you're wondering what our rationale is for doing so when we determined that the resistance and support points (along with the emerging descending triangle pattern) is forecasting bearish price action.</p>
<h3 id="heading-librehash-reversion-ribbon-v2"><strong>Librehash Reversion Ribbon v2</strong></h3>
<p>We'll start with the Librehash Reversion Ribbon v2 first (<em>custom indicator</em>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718660489/656ca9e6-4aec-4446-b382-e00ecec4659a.png" alt class="image--center mx-auto" /></p>
<p>Below are some things worth noting:</p>
<ol>
<li><p>Recently, the ribbon has 'reverted'. This means that the faster moving average has crossed above the slower one. That's a sign of a trend reversal. As we can see, this occurred on the daily resolution about 3 or so days ago (<em>we'll identify that after this mini-section</em>).</p>
</li>
<li><p>The ribbon itself is still below the histogram. However, we can see that the ribbon's direction has pivoted to ascending from its prior downward slope.</p>
</li>
<li><p>The histogram also reveals that the ribbon (<em>now green &amp; signaling bullish activity</em>) is still expanding for each successive bar preceding it over the past 6 periods. That's pretty bullish (<em>at least in the short-term</em>). This signals increasing buy pressure for Bitcoin on the daily resolution during this span of time.</p>
</li>
</ol>
<p>With those points established, let's take a look at the annotated chart formation below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718680616/28079243-021f-4607-89c1-e319f74a2ee3.png" alt class="image--center mx-auto" /></p>
<p>Now let's check out a few other indicators to see what they're telling us here on the daily resolution.</p>
<h4 id="heading-exponential-moving-averages">Exponential Moving Averages</h4>
<p>From here, we're going to take a look at the exponential moving averages for Bitcoin (<em>we'll cover our rationale for why we use the EMAs vs. the other moving average types</em>).</p>
<p>Check out the chart below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718704909/ade294ff-be35-4b6e-8fa3-90d7f4cfa347.png" alt class="image--center mx-auto" /></p>
<p>In the chart above we have the EMA-12 (purple), EMA-26 (green) and the EMA-50 (yellow) lines plotted out.</p>
<p>As we can see in the chart above, the EMA's are stacked in the following order: EMA50 &gt; EMA26 &gt; EMA12.</p>
<p>That's a bearish stack.</p>
<p><strong>However, there are a few things worth noting</strong>:</p>
<ol>
<li><p>There is an underlying support at $57.1k which is created with the EMA-12.</p>
</li>
<li><p>There are two overhead resistance points created by the EMA-26 and EMA-50. The EMA-26 gives us an overhead resistance at $58.3k and the EMA-50 gives us resistance at $59.6k.</p>
</li>
<li><p>Typically, when it comes to gauging the strength of the resistance or support conferred by EMA indicators, strength is positively correlated with the time frame of lookback on the indicator. So in laymen's terms what that means is that the longer the EMA period, the stronger the resistance or support point will be. So the EMA-50 will provide a greater resistance to price than the EMA-12 or EMA-26 would.</p>
</li>
</ol>
<p>If we pan back out a little further and add on the EMA-100 and EMA-200 to our chart, we'll gain a lot more insight about the true status of Bitcoin's market cycle.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718731215/373fe9b9-3b07-407b-889a-01ac57f1e22a.png" alt class="image--center mx-auto" /></p>
<p>In the screenshot above, we have the EMA-50 (golden line), EMA-100 (red line) and the EMA-200 (blue line).</p>
<p>There are a few substantial observations to be noted here:</p>
<ol>
<li><p><strong>Death Cross Has Not Occurred</strong>: <a target="_blank" href="https://www.coindesk.com/markets/2024/08/06/bitcoins-unreliable-death-cross-is-looming-again/">Numerous media outlets have claimed</a> that a death cross formed or is in the process of forming over the past few weeks. As a quick refresher, a 'death cross' is symbolized by a 50 period moving average <strong>crossing below</strong> a 200 period moving average. In the article I linked here from CoinDesk, the author mentioned the alleged imminent crossing of the 50-day SMA (simple moving average) below the 200-day SMA. However, for an asset like Bitcoin we want to look at the <strong>exponential moving averages</strong>, not the SMA or other MA indicators. This is to account for the exponential change (positive or negative) in Bitcoin's price over the past 50 to 200 days.</p>
</li>
<li><p><strong>All Averages are Within ~5% of the Current Price</strong> - This singular factor presents one of the most compelling cases for bulls (<em>among all overlay indicators, resistance/support points, etc.</em>). To be clear, when I say that all averages are within ~5% of the current price, I'm stating that among all essential EMA lookbacks (12, 26, 50, 100 and 200), the EMA that's furthest away from Bitcoin's current value only deviates from it by ~5%. Elaborating on that last point above, the EMA that is the furthest distance away from the current price action is the EMA-200. At the time of writing, its value is sitting at $60.9k.</p>
</li>
</ol>
<p>Check that out below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718748256/28685840-dfea-4f10-9269-45fb5c1edf1e.png" alt class="image--center mx-auto" /></p>
<p><strong>What This Means</strong></p>
<p>If we pan out our charts a little bit, we can see that this price also coincides with some other notable 'tested' supports and resistance points on the daily resolution.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718770530/b8eeb96b-4f33-4a4c-91fb-be4c34f7db8d.png" alt class="image--center mx-auto" /></p>
<p>As we can see on the chart above, this price point has served as a tested support/resistance point 8 different times since March 2024 (<em>that's only 6 months</em>).</p>
<p><strong>Why This is Significant</strong></p>
<p>In situations where there is a major support/resistance point on an asset's price chart and that asset happens to break through that support or resistance with opposing force (i.e., bulls busting through a resistance; bears busting below a support), the price action typically surges from that point going forward.</p>
<p>Let's check out some examples of Bitcoin's price action spanning back to March 2024 in instances where the price fell below or was already below this overhead resistance and it ended up breaking through.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718845373/a54c6987-3b74-4493-9d85-12cc26f1eb65.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718850930/005e26bc-18f9-4ede-9c8e-b10732dbb625.png" alt class="image--center mx-auto" /></p>
<p>Here are the actual results (<em>and specific time frames</em>):</p>
<ul>
<li><p><strong>February 28th, 2024-March 13th, 2024</strong>: +27.56%</p>
</li>
<li><p><strong>May 2nd, 2024 - May 21st, 2024</strong>: +22.82%</p>
</li>
<li><p><strong>July 7th, 2024 - July 21st, 2024</strong>: +21.93%</p>
</li>
<li><p><strong>August 5th, 2024 - August 8th, 2024</strong>: +14.13%</p>
</li>
<li><p><strong>August 16th, 2024 - August 25th, 2024</strong>: +11.52%</p>
</li>
</ul>
<p>Additionally, in instances where the price had broken above this overhead resistance (<em>converting it to a support</em>) then faced a later correction that plunged it below the newly created underlying support, the net decline in price <strong>below that threshold</strong> has always been limited (<em>compared to the overall descent from the price's prior localized top</em>).</p>
<p>Below are some examples to emphasize what I mean:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718878078/f2d7ad92-733f-4195-9f81-84c179bcc2ef.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>April 30th, 2024 - May 2nd, 2024</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718897762/171d5391-9dde-494f-a4cf-7962a1308111.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>July 4th, 2024 - July 8th, 2024</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718918631/d9f31b8a-fd6b-49c1-a252-8044db1e1e58.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>August 4th, 2024 - August 6th, 2024</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718940186/a50ee7a2-9bad-4ec7-b0c1-e5e90795dbfa.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>August 14th, 2024 - August 15th, 2024</em></p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718955028/595f0b7e-4540-43e8-8f7d-6fe824cfc3c9.png" alt class="image--center mx-auto" /></p>
<p>As we can see from the examples above, the furthest the price has corrected below the current major overhead resistance ($59k), has been approximately ~10%. Which, normally would be considered to be a steep loss. But when dealing with an asset that's as volatile as Bitcoin, this is far from anything one could consider to be a "major loss" within the scope of Bitcoin and cryptocurrency price changes.</p>
<h4 id="heading-brief-price-update">Brief Price Update</h4>
<blockquote>
<p><em>Similar to the prior section, we're doing an intermittent update on our price analysis to see what these EMA values are reading at the time of writing and what that means for Bitcoin's price moving forward</em>.</p>
</blockquote>
<p>Below is a chart overlaid with each EMA that we discussed above:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718974254/907c2dbf-f42d-4d46-83dd-5a94f74f834c.png" alt class="image--center mx-auto" /></p>
<p>In this chart, we have the EMA-12 (dark purple), EMA-26 (green line), EMA-50 (golden line), EMA-100 (blue) and EMA-200 (red). As we can see, all of the EMA indicators are bunched up together here, which tells us that the price hasn't deviated that much over the past 200 periods.</p>
<p>As we can see, the price has broken above the EMA-12, EMA-26, EMA-50 and EMA-200 (curiously), making each one of these points an underlying support now. Our overhead resistance now is posed by the EMA-100 (red line). The EMA-100 line is <strong>just below</strong> the resistance zone that we marked through the overhead diagonal downtrend resistance.</p>
<p>So we have two strong overhead resistance points. This is something <strong>worthy of note</strong>. Now let's go on to see the values for the rest of the indicators.</p>
<h3 id="heading-balance-of-power-rsi">Balance of Power RSI</h3>
<p>This indicator is a custom one that I created with a special purpose. It integrates the RSI and the normal "Balance of Power" indicator alongside an EMA indicator to smooth the values and give us an intelligible reading.</p>
<p>What makes the Balance of Power RSI so useful is the fact that it forecasts changes in buy or sell pressure that diverge significantly from current price action. In other words, this is a great indicator to use when you're looking to gauge true market sentiment at a given point in time.</p>
<p>Let's see what values the indicator is giving us at at the time of writing:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726718998474/04122c6b-229d-410e-a82c-39166bdc2c03.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>Above, we can see the Balance of Power has shot straight up and is close to breaking outside of the neutral zone</em> (purple background).</p>
</blockquote>
<p>As we can see above, the Balance of Power RSI has soared from a zone of extreme selling pressure to extreme buy pressure. Typically, this reflects a surge in bullish price action.</p>
<p>However, when considering the price's stagnation at the two major overhead resistance points that we identified earlier, the stagnation in price action is worth noting in light of the Balance of Power RSI's reading.</p>
<h3 id="heading-librehash-rsi14">Librehash RSI(14)</h3>
<blockquote>
<p>Here's another custom indicator. What makes this one particularly useful is the fact that it takes the usual RSI(14) and then provides a color change for the indicator whenever an EMA(9) of the RSI(14) crosses above or below a slower exponential moving average. This methodology was made concrete back in 2018 and has proven to be a reliable measure of price action ever since.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726719020331/decbefef-8751-47d8-a071-2420d9723dcc.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p><em>We're going to break this down a lot further because the RSI(14) isn't reading the way you might think it is from first glance</em></p>
</blockquote>
<p>Right now, the Librehash RSI is flashing green, which shows an increase in momentum. Additionally, the indicator has pivoted upward since September 5th, 2024.</p>
<p>However, we're going to take a look at one critical factor that undermines any potential bullish reading that we could extract from the RSI.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726719050668/6bbda731-3569-47a0-b778-600ee40c5338.png" alt class="image--center mx-auto" /></p>
<p>In the chart above, we can see that the RSI has made successively lower highs spanning back to July 2024. The next 'lower high' came in late August 2024. And now, a little past midway in September, we are once again seeing what appears to be an even lower high than the one immediately preceding it a month prior.</p>
<p>Within the scope of interpreting the RSI indicator, this should be interpreted as <strong>bearish</strong>. It signals an overall decrease in price momentum. The next question to ask ourselves now is whether this represents a continuation of an already existing bearish trend or bearish divergence.</p>
<ol>
<li><p><strong>Bearish Divergence</strong> - This occurs when the RSI is making 'lower highs' while the price (at the same time) is making 'higher highs'. So, for example, let's say the price of Bitcoin were $45k at the first high. Then at the second high, it was at $52k. Then at the 3rd high, it was $60k. In that scenario, we would have what's called "<strong>bearish divergence</strong>". This essentially means that the indicator is showing an underlying weakening of bullish momentum over a span of time in a way that suggests the ongoing price rally in that scenario is running out of fuel. In such cases, traders would be wise to begin looking out for potential reverses and/or events or other technical indicators that can be used to confirm the (potentially) impending bearish price action.</p>
</li>
<li><p><strong>Bearish Continuation</strong> - This scenario is a bit more simple. Once again, we'll assume the Librehash RSI in our fictional example is showing the same values they are on our Bitcoin chart presently. However, when the first high was reached, the price of Bitcoin was $64k. When the RSI notched its second (lower) high, the price of Bitcoin was at $58k. And when the RSI notched its third successively lower high, the price of Bitcoin shrunk down to $54k. In that instance, we would have what's called a "bearish continuation". Simply put, the term is defined intuitively as defining a scenario where whatever bearish trend was prevailing at the time of the analysis will simply continue.</p>
</li>
</ol>
<p>In order to assess which situation we're dealing with, we need to take a look at where the price when the Librehash RSI was notching these consecutive, successive lower highs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726719140781/097f3020-3d71-4ca7-a53f-2055827f3671.png" alt class="image--center mx-auto" /></p>
<p>As we can see in the chart above, these consecutive successively lower highs from the Librehash RSI span from July to September (currently). These events occurred on July 21st, August 25th and September 13th (<em>just a few days ago</em>).</p>
<p>Below we have Bitcoin's price (closing) on those dates:</p>
<ul>
<li><p><strong>July 21st, 2024</strong>: $68,818</p>
</li>
<li><p><strong>August 25th, 2024</strong>: $64,251</p>
</li>
<li><p><strong>September 13th, 2024</strong>: $60,543</p>
</li>
</ul>
<p>So we can definitively state that the price also notched lower highs that corresponded with those dates as well. So what we have here is a <strong>bearish continuation</strong>.</p>
<p>So that should be all for our RSI reading then, correct? <strong>Not so fast</strong>.</p>
<h4 id="heading-conflicting-rsi-signal">Conflicting RSI Signal</h4>
<p>If you were looking carefully at the original Librehash RSI chart that we posted up, you may have noticed that while there were successively lower highs being formed by the RSI, we also saw successively <strong>higher lows</strong> at the same time.</p>
<p>For those that are students of technical analysis, we know that this is considered to be a <strong>bullish</strong> signal within the scope of RSI.</p>
<p>In case you missed it, let's go ahead and take a another look at our RSI chart below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726719168398/cb5f252d-bb63-4f24-9028-4d1110ac2a6c.png" alt class="image--center mx-auto" /></p>
<p>As we can see above, there are two successively higher lows that have been notched. They occurred on August 8th, 2024, and September 10th, 2024, respectively.</p>
<p>Now let's take a look at what Bitcoin's price was on those respective dates.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726719183193/4fc621aa-7b85-45d9-83e4-1bdc664ea0ea.png" alt class="image--center mx-auto" /></p>
<p>Bitcoin's price on those two dates (<em>from the chart above</em>):</p>
<ul>
<li><p><strong>August 8th, 2024</strong>: $61,705</p>
</li>
<li><p><strong>September 10th, 2024</strong>: $57,645</p>
</li>
</ul>
<p>With this information in-hand, we can now say that the RSI is also showing us <strong>bullish divergence</strong> alongside a <strong>bearish continuation</strong>. So which one will prevail?</p>
<p><strong>How to Interpret these Readings</strong></p>
<p>If you're confused, don't worry. We're going to break down what's going on and what this means right now. First, we're going to recap all the observations we made related to Bitcoin's RSI.</p>
<p>Right now we're looking at the RSI for a given price chart and we can see that it has made successively lower highs. During that point in time, the price has also notched lower highs. Also, the RSI has notched 3 successively higher lows over that same span of time. This is normally seen as an increase in buy pressure while the sell pressure has decreased gradually.</p>
<p>However, during those successively higher lows, the asset notched consecutive successively lower prices over that span of time too. Conventionally, this should indicate some underlying positive divergence as well.</p>
<p>All of this results in RSI values that make the indicator look as though it's in the 'flag' part of a pennant formation. However, the only difference here is that it's not easy for us to gauge where the price may go due to the conflicting signals given by the indicator. Therefore, we're going to have to wait until the indicator provides a value that makes it impossible for the other trend to remain true.</p>
<p>The reason why this must be the case is because the RSI cannot keep consistently notching lower highs while also making higher lows because, at some point, one must surpass the other.</p>
<p>Either the next 'lower high' must be lower than what the next higher low could be, or vice versa. Thus, based on charting logic, it stands to reason that we won't truly know how the price will move until we see the RSI 'break out' of this pennant-like formation that it is in and head either north or south of our flag formation.</p>
<p><strong>To recap, what we know thus far about the RSI is that:</strong></p>
<ol>
<li><p>It has posed consecutive, successively lower highs over the past 3 months for a certain asset.</p>
</li>
<li><p>That certain asset has also had consecutive successively lower price values that have coincided with these lower highs of the RSI. We understand this to be indicative of a bearish continuation within the scope of interpreting the RSI indicator.</p>
</li>
<li><p>During this same span of time, the RSI has also notched consecutive successively higher lows for a certain asset.</p>
</li>
<li><p>At the times that those consecutively higher lows were notched, the price of this certain asset was consecutively lower. That means that in this scope of our RSI interpretation, we can detect bullish divergence in the price action.</p>
</li>
</ol>
<h3 id="heading-conclusion">Conclusion</h3>
<p><s>With all things considered, the overall forecast for Bitcoin here in this price analysis is </s> <strong><s>bearish</s></strong><s>. Even though many of our indicators are giving readings close to the overbought / extreme buy pressure range, that still doesn't nullify the existence of a remarkably strong </s> <strong><s>overhead diagonal downtrend resistance</s></strong><s>, coupled with the overhead resistance posed by the EMA-100.</s></p>
<p><s>Beyond that, there's also the fact that Bitcoin is in a bearish chart formation (descending triangle) that has been playing out according to script at this point.</s></p>
<p><s>With that being said, we're going to go ahead and chart our proposed short on Bitcoin.</s> In the time it took me to get around to writing this conclusion, I discovered that Bitcoin had broken above its overhead diagonal resistance (surprise, surprise).</p>
<p>Let's check out the most recent price action.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726719675095/11a31636-d66a-4e9b-82f9-0e920504720a.png" alt class="image--center mx-auto" /></p>
<p>With that being said, I’m going to have to revise my initial analysis and flip this over to bullish. Bitcoin broke above a major overhead diagonal downtrend resistance. And it did so with volume. Plus the candles are looking strong too. Everything I see here is screaming buy at this point. These are all the bullish signals we were looking for when this analysis was first done.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726768727284/c6f49339-e9fd-4b7c-be79-df2c384b8e2a.png" alt class="image--center mx-auto" /></p>
<p>So everything we said about the lower highs has been invalidated. The higher lows are no longer relevant as well. What we have now is <strong>bullish divergence</strong>. That, coupled with Bitcoin’s break above the overhead resistance, is <strong>extremely bullish</strong>.</p>
<p>Therefore, our R/R on this trade is as follows:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726768796496/1ef2d706-1187-49be-b79a-8af9a40ae273.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Avalanche Protocol Signature Exploit: Part Four]]></title><description><![CDATA[Since Avalanche chose to screw me out of a $10k bug bounty, I've elected to publish this research for free for the benefit of the community. While I have no problem doing so, the key to being able to continue publishing such research is sustainabilit...]]></description><link>https://librehash.xyz/avalanche-protocol-signature-exploit-part-four</link><guid isPermaLink="true">https://librehash.xyz/avalanche-protocol-signature-exploit-part-four</guid><category><![CDATA[Avalanche]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Blockchain]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Sun, 19 Feb 2023 06:33:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676786839019/a46be56c-9c95-4ff3-b9fe-b7bc31bdac59.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Since Avalanche chose to screw me out of a $10k bug bounty, I've elected to publish this research for free for the benefit of the community. While I have no problem doing so, the key to being able to continue publishing such research is sustainability.</p>
<p>Thus, I have a tip jar (Bitcoin) hosted here for all those that would like to show their appreciation or simply contribute. Thanks!</p>
<p>Bitcoin: 1HJTmhDovvLTWosyucb2dEFKJwWAfQqKn2</p>
<p>ETH: 0xa84c0ae8c7aea26e5956c3b5febd167c93be0d05</p>
</blockquote>
<p>Sadly, it's come to this. After reporting a potent issue in the Golang cryptographic library used by Avalanche on February 14th, 2023, I expected that the team was going to address this issue since it was so obvious and well-documented.</p>
<p>I'm not going to waste too much time re-summarizing the core issue at hand since they've already been covered <strong>ad nauseum</strong> in the <a target="_blank" href="t.me/librehash">Telegram channel</a> and <a target="_blank" href="https://librechain.org">in previous posts on this blog</a>.</p>
<h2 id="heading-avalanchego-does-not-generate-proper-signatures">AvalancheGo Does Not Generate Proper Signatures</h2>
<p>We're going to prove that the AvalancheGo does not generate signatures properly. The AvalancheGo <a target="_blank" href="https://github.com/ava-labs/avalanchego">main repo can be found here</a>.</p>
<p><strong>Instructions</strong>:</p>
<ol>
<li><p><code>git clone</code> <a target="_blank" href="https://github.com/ava-labs/avalanchego.git"><code>https://github.com/ava-labs/avalanchego.git</code></a></p>
</li>
<li><p><code>cd avalanchego</code></p>
</li>
<li><p><code>cd main</code></p>
</li>
</ol>
<p>Once in the <code>main/</code> directory, we're going to run <code>rm -r main.go</code>. We're going to replace this file with another one that I wrote to directly test the signatures generated with the repo.</p>
<p>I have that file <a target="_blank" href="https://gist.github.com/Librechain/ad0a5dc921f47604baf830fc478ceaa4">hosted on GitHub as a gist</a>. For those too lazy to visit, the source code is published below:</p>
<pre><code class="lang-golang"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
  <span class="hljs-string">"encoding/hex"</span>
  <span class="hljs-string">"fmt"</span>

  <span class="hljs-string">"github.com/ava-labs/avalanchego/utils/crypto"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
  <span class="hljs-comment">// Hexadecimal private key</span>
  privateKeyHex := <span class="hljs-string">"eeac0e3d8f0fcc32a553cc5ab8dad48a435bb4c047d95b06eb7a29a4a823e87c"</span>

  <span class="hljs-comment">// Parse the private key</span>
  privateKeyBytes, _ := hex.DecodeString(privateKeyHex)

  <span class="hljs-comment">// Create a new private key object from the parsed bytes</span>
  <span class="hljs-comment">// factory := &amp;FactorySECP256K1R{}</span>
  factory := &amp;crypto.FactorySECP256K1R{}
  privateKey, err := factory.ToPrivateKey(privateKeyBytes)
  <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
    <span class="hljs-built_in">panic</span>(err)
  }

  <span class="hljs-comment">// Print the private key in hex format</span>
  fmt.Printf(<span class="hljs-string">"Private key: %x\n"</span>, privateKeyBytes)

  <span class="hljs-comment">// Derive the public key from the private key</span>
  publicKey := privateKey.PublicKey()

  <span class="hljs-comment">// Print the public key in hex format</span>
  fmt.Printf(<span class="hljs-string">"Public key: %x\n"</span>, publicKey.Bytes())

  <span class="hljs-comment">// Sign a message using the private key</span>
  message := []<span class="hljs-keyword">byte</span>(<span class="hljs-string">"avalanchesignature"</span>)
  signature, err := privateKey.Sign(message)
  <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
    <span class="hljs-built_in">panic</span>(err)
  }

  <span class="hljs-comment">// Parse the signature</span>
 <span class="hljs-comment">// r, s, v, err := parseSignature(signature)</span>
 <span class="hljs-comment">// if err != nil {</span>
 <span class="hljs-comment">//   panic(err)</span>
 <span class="hljs-comment">// }</span>

  <span class="hljs-comment">// Print the signature and its components</span>
  fmt.Printf(<span class="hljs-string">"Signature: %x\n"</span>, signature)
<span class="hljs-comment">//  fmt.Printf("r: %d\n", r)</span>
<span class="hljs-comment">//  fmt.Printf("s: %x\n", s)</span>
<span class="hljs-comment">//  fmt.Printf("v: %d\n", v)</span>
}
</code></pre>
<p>Once we have the code, we're going to copy/paste it into the <code>main/</code> directory and name it <code>main.go</code>.</p>
<p><strong>Brief Explanation of What This Code Does</strong></p>
<ol>
<li><p>This code takes a hexadecimal private key (<code>eeac0e3d8...823e87c</code>).</p>
</li>
<li><p>The key is parsed.</p>
</li>
<li><p>We create a new private key from the parsed bytes using <code>factory := &amp;crypto.FactorySECP256K1R</code>. I'm mentioning this part to make it clear that we're using the AvalancheGo library specifically (<em>which we have linked in the header underneath the import statement</em>).</p>
</li>
<li><p>The code then uses that same library to derive the public key from said private key.</p>
</li>
<li><p>We then sign a message. That message is <code>avalanchesignature</code>.</p>
</li>
<li><p><em>Code to parse the signature was omitted due to time constraints and it being slightly outside of the scope of what we need to do here</em></p>
</li>
<li><p>Signature is created with the private key signing over the message we identified in step 5. The function called to perform the signing operation is <code>Sign</code>, which is a call directly to the AvalancheGo library cited at the top in the import statement.</p>
</li>
</ol>
<p><strong>Iterating the Code</strong></p>
<p>Assuming you all have edited <code>main.go</code> all you have to do now is enter the command: <code>go run main.go</code>.</p>
<p>This will result in the following output being spit back out at you:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932057-e9052cf9-cdd1-4d54-b2c6-aba8263e4452.png" alt="image" /></p>
<p>Most importantly, we have the <code>CompactSignature</code> in DER format.</p>
<p>Expanding that value to derive the serialized DER hash yields us: <code>3045022100c5d2d9a05c2cdb34f4260dd18ba52eb5b041c8edb52eb9bae9b0743580adb9c302202f092fc8ae6fa720ebd99894ce9d7fcc473be582959eed8b9ac0b9a0c9265f06</code>.</p>
<p>We'll see a bit further along that this signature, while valid, <strong>is not in accordance with the RFC6979 standard</strong>.</p>
<h3 id="heading-comparing-the-hash-produced-to-decreds-library">Comparing the Hash Produced to Decred's Library</h3>
<p>Even though Decred is listed in the header of the <code>secp256k1r.go</code> file as an import, very little of the code pulls from functions in that library.</p>
<p>This is worth noting because when the Avalanche team sent me a longform documented response to the "claims" I had raised, they erroneously (and falsely) claimed that their library inherited several functions from this library that it <strong>in fact, didn't</strong>.</p>
<p>Below is an excerpt from that communication.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932061-8e5ee8d5-242e-4969-bf36-970b0e6fe559.png" alt="image" /></p>
<p>The two functions in the screenshot above that the team referenced are <code>Sign</code> and <code>SignHash</code>.</p>
<p>This clearly isn't the case and proving otherwise was a trivial task handled through VSCode (see below).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932065-7786a1dc-6e4b-4df5-9cde-31fe748d75bc.png" alt="image" /></p>
<p>The function takes us to the <a target="_blank" href="https://pkg.go.dev/github.com/ava-labs/avalanchego@v1.9.8/utils/crypto#PrivateKeySECP256K1R.Sign">AvalancheGo Golang package</a>.</p>
<p>Some functions derive from the Decred library, but this is <strong>not the library that governs how the secp256k1 signatures are formed</strong>.</p>
<p>This is a critical distinction to make because it is one of the chief claims that the Avalanche team made in their denial of the <strong>real attack vector</strong> their project faces.</p>
<h3 id="heading-comparing-decred-signatures-vs-avalanche">Comparing Decred Signatures vs. Avalanche</h3>
<p>The Decred code properly formulates signatures in accordance with RFC6979. As noted in one of the other reports published, the Avalanche team claimed that their code <strong>also provided such signatures</strong>. However, this is <strong>not true</strong>.</p>
<p>As a brief Proof of Concept for this issue, I took the same private key and message to be signed that you all saw earlier and produced a DER-encoded signature output that was <strong>different</strong> from what we saw with Avalanche's code.</p>
<p>That code <a target="_blank" href="https://go.dev/play/p/OTE7LHkRWkp">can be found here</a>.</p>
<p>Below is the literal code produced to create the signature.</p>
<pre><code class="lang-golang"><span class="hljs-keyword">package</span> main

<span class="hljs-keyword">import</span> (
    <span class="hljs-string">"encoding/hex"</span>
    <span class="hljs-string">"fmt"</span>

    <span class="hljs-string">"github.com/decred/dcrd/dcrec/secp256k1/v3"</span>
    <span class="hljs-string">"github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa"</span>
)

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
    <span class="hljs-comment">// Hexadecimal private key</span>
    <span class="hljs-comment">// (ignore) privateKeyHex := "99f0cf7355bffdeea25728a93848595f8ac65596f244501fd167717f969b18f2"</span>

    <span class="hljs-comment">// Decode a hex-encoded private key.</span>
    pkBytes, err := hex.DecodeString(<span class="hljs-string">"eeac0e3d8f0fcc32a553cc5ab8dad48a435bb4c047d95b06eb7a29a4a823e87c"</span>)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        fmt.Println(err)
        <span class="hljs-keyword">return</span>
    }
    privKey := secp256k1.PrivKeyFromBytes(pkBytes)

    <span class="hljs-comment">// Parse the private key</span>
    <span class="hljs-comment">// privateKeyBytes, _ := hex.DecodeString(privateKeyHex)</span>

    <span class="hljs-comment">// Create a new private key object from the parsed bytes</span>
    <span class="hljs-comment">// factory := &amp;FactorySECP256K1R{}</span>
    <span class="hljs-comment">//  factory := &amp;crypto.FactorySECP256K1R{}</span>
    <span class="hljs-comment">//  privateKey, err := factory.ToPrivateKey(privateKeyBytes)</span>
    <span class="hljs-comment">//  if err != nil {</span>
    <span class="hljs-comment">//   panic(err)</span>
    <span class="hljs-comment">// }</span>

    <span class="hljs-comment">// Print the private key in hex format</span>
    fmt.Printf(<span class="hljs-string">"Private key: %x\n"</span>, privKey)

    <span class="hljs-comment">// Derive the public key from the private key</span>
    <span class="hljs-comment">// publicKey := privKey.PublicKey()</span>

    <span class="hljs-comment">// Print the public key in hex format</span>
    <span class="hljs-comment">// fmt.Printf("Public key: %x\n", publicKey.Bytes())</span>

    <span class="hljs-comment">// Sign a message using the private key</span>
    message := <span class="hljs-string">"avalanchesignature"</span>
    <span class="hljs-comment">// message := []byte("Hello, world!")</span>

    <span class="hljs-comment">// messageHash := chainhash.HashB([]byte(message))</span>
    signature := ecdsa.Sign(privKey, []<span class="hljs-keyword">byte</span>(message))

    fmt.Printf(<span class="hljs-string">"Signature: %x\n"</span>, signature)
    <span class="hljs-comment">//  signature, err := privateKey.Sign(message)</span>
    <span class="hljs-comment">//  if err != nil {</span>
    <span class="hljs-comment">//   panic(err)</span>
    <span class="hljs-comment">//  }</span>

    <span class="hljs-comment">// Parse the signature</span>

    <span class="hljs-comment">// Print the signature and its components</span>
    fmt.Printf(<span class="hljs-string">"Signature: %x\n"</span>, signature)

    <span class="hljs-comment">// Serialize and display the signature.</span>
    fmt.Printf(<span class="hljs-string">"Serialized Signature: %x\n"</span>, signature.Serialize())
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">parseSignature</span><span class="hljs-params">(sig []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-params">(r <span class="hljs-keyword">int64</span>, s []<span class="hljs-keyword">byte</span>, v <span class="hljs-keyword">int64</span>, err error)</span></span> {
    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(sig) != <span class="hljs-number">65</span> {
        err = fmt.Errorf(<span class="hljs-string">"invalid signature length: %d"</span>, <span class="hljs-built_in">len</span>(sig))
        <span class="hljs-keyword">return</span>
    }
    r = <span class="hljs-keyword">int64</span>(sig[<span class="hljs-number">0</span>])
    s = sig[<span class="hljs-number">1</span>:<span class="hljs-number">33</span>]
    v = <span class="hljs-keyword">int64</span>(sig[<span class="hljs-number">64</span>])

    fmt.Printf(<span class="hljs-string">"r: %d\n"</span>, r)
    fmt.Printf(<span class="hljs-string">"s: %x\n"</span>, s)
    fmt.Printf(<span class="hljs-string">"v: %d\n"</span>, v)
    <span class="hljs-keyword">return</span>
}
</code></pre>
<p><strong>Here is the Signature that Gets Produced</strong>: 3044022005c8e48a951107d993d2b787ddc1a3920343690dbaa306c1869299b396645704022058c37b2833467037be9cc49947f4a6920a3fa86c923a295376dc2a011e6a77e8</p>
<blockquote>
<p>Here's the Avalanche signature we produced earlier: <code>3045022100c5d2d9a05c2cdb34f4260dd18ba52eb5b041c8edb52eb9bae9b0743580adb9c302202f092fc8ae6fa720ebd99894ce9d7fcc473be582959eed8b9ac0b9a0c9265f06</code></p>
<p>See the difference?</p>
</blockquote>
<p>If the Avalanche library derived its signatures from the Decred Golang library, then it would've produced the same DER-encoded signature.</p>
<h1 id="heading-compromising-validators-on-avalanche">Compromising Validators on Avalanche</h1>
<blockquote>
<p><strong>Disclaimer</strong>: <em>We're merely going to walkthrough how someone could compromise validators</em> (in theory). <em>This has not been executed in practice by myself as it goes against my personal code of ethics. The author of this research shares no liability in how someone chooses to use this research. This is not a call to action or an encouragement to engage in any particular activity. Any and all consequences you incur for your actions are on you</em>.</p>
</blockquote>
<p>As mentioned before, one of the issues with Avalanche not generating deterministic signatures per RFC6979's specification is that the signatures created lead to private key recovery.</p>
<p>Thus, as promised, we're going to walkthrough how one <strong>could compromise validators</strong> (<em>in theory</em>). This theory has not been executed in practice because I am neither hacker nor a blackhat of any sort</p>
<p>Even if the signatures produced by Avalanche are deterministic (which they are), if the nonces used in the creation of said signatures are <strong>biased</strong> in some way.</p>
<h2 id="heading-lattice-attacks-on-ecdsa">Lattice Attacks on ECDSA</h2>
<p>The attack vector we're going to explore here is called a 'lattice attack' on ECDSA.</p>
<p>The guide we'll use <a target="_blank" href="https://forum.vac.dev/t/lattice-attacks-on-ecdsa/136">can be found here</a>. As noted in the post, "<em>The attack is based on the theory of short vectors in lattices and uses the LLL algorithm to recover the private key from multiple (biased) signatures.</em>"</p>
<p>An example repo that explores this attack <a target="_blank" href="https://github.com/bitlogik/lattice-attack">can be found here</a> (<em>with accompanying Python code</em>). For diversity of options, here's <a target="_blank" href="https://github.com/daedalus/BreakingECDSAwithLLL">another repo that you can reference that provides a guide/walkthrough on these attacks</a>, <a target="_blank" href="https://github.com/daedalus/BreakingECDSAwithLLL/blob/master/crack_weak_ECDSA_nonces_with_LLL.py">with accompanying Python code</a>.</p>
<p>If you're looking for a Python script reference that <strong>exploits this attack on Bitcoin signatures</strong>, <a target="_blank" href="https://github.com/daedalus/bitcoin-recover-privkey/blob/master/ProofOfConcept.py">look no further than here</a>. If you're looking for some potentially exploitable signatures among the blockchain's extensive, 10+ year-long history of operation, <a target="_blank" href="https://strm.sh/studies/bitcoin-nonce-reuse-attack/">this blog post should serve as an adequate reference</a>.</p>
<h3 id="heading-brief-dive-into-the-methodology">Brief Dive into the Methodology</h3>
<p>Don't worry, we're not going to dig into the trenches here as far as the mathematical principles behind lattice attacks. Instead, we're going to explore the methodology necessary to implement this attack <strong>in practice</strong>.</p>
<p>To start, refer to the brief excerpt from the '<a target="_blank" href="https://forum.vac.dev/t/lattice-attacks-on-ecdsa/136">Lattice Attacks on ECDSA</a>' guide we referenced earlier.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932077-ecb5cffd-b6fa-4913-aa8c-c12abf6f405c.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932092-5468357c-dd3a-4569-8501-84ce82052d87.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932094-acfb8eed-414a-490a-97a8-84ae2290c0c9.png" alt="image" /></p>
<p>Ok, so maybe I lied about the math part - but the above was published for coherency purposes.</p>
<p>From here, let's explore the example Python script given which generates 40 signatures over random messages deriving a private key. As stated in the post, "<em>the signature[s] are generated so that the employed nonce are biased by having the first</em> <code>bias = 1</code> <em>bytes set to zero</em>."</p>
<p>The relevant Python code can be found below.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> ecdsa.ecdsa <span class="hljs-keyword">import</span> curve_256, generator_256, Public_key, Private_key
<span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> randbytes, randint

G = generator_256
p = G.order()

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">genKeyPair</span>():</span>
    d = randint(<span class="hljs-number">1</span>,p<span class="hljs-number">-1</span>)
    pubkey = Public_key(G, d*G)
    privkey = Private_key(pubkey, d)
    <span class="hljs-keyword">return</span> pubkey, privkey

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sign</span>(<span class="hljs-params">privkey, bias</span>):</span>
    m = randbytes(<span class="hljs-number">32</span>)
    nonce = randbytes(<span class="hljs-number">32</span> - bias)
    sig = privkey.sign(int.from_bytes(m, <span class="hljs-string">"big"</span>), int.from_bytes(nonce, <span class="hljs-string">"big"</span>))
    <span class="hljs-keyword">return</span> (m, sig.r, sig.s)

pubkey,privkey = genKeyPair()
print(<span class="hljs-string">'Public key:'</span>, (int(pubkey.point.x()), int(pubkey.point.y())))
print(<span class="hljs-string">'Private key:'</span>, int(privkey.secret_multiplier))

SIGs = []
<span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> range(<span class="hljs-number">40</span>):
    SIGs += [sign(privkey, <span class="hljs-number">1</span>)]

SIGs
</code></pre>
<p>Note that running this script requires installing the python module ecdsa first (<code>pip install ecdsa</code>).</p>
<p>From here, you'll need to have '<a target="_blank" href="https://www.sagemath.org/">SageMath</a>' installed in order to run the next bit of Python code.</p>
<p>If you're following along, please note that you're going to have to:</p>
<ol>
<li><p>Find the relevant public key for the signatures you're examining (<em>you can recover this trivially on Avalanche since th is is a feature of the signatures that are produced on that chain</em>).</p>
</li>
<li><p>We're going to need to replace the elliptic curve parameters at the top of the file as well.</p>
</li>
</ol>
<p>If you visit that blog post, the elliptic curve parameters presented are:</p>
<pre><code class="lang-plaintext">q = 115792089210356248762697446949407573530086143415290314195533631308867097853951
A = -3
B = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
F = GF(q)
E = EllipticCurve(F,[A,B])
Gx = 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
Gy = 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
G = E(Gx,Gy)
p = 115792089210356248762697446949407573529996955224135760342422259061068512044369
assert G.order() == p
</code></pre>
<p>Here's what they should be (<strong>secp256k1</strong>):</p>
<pre><code class="lang-plaintext">q = 115792089237316195423570985008687907853269984665640564039457584007908834671663
A = 0
B = 0x07
F = GF(q)
E = EllipticCurve(F,[A,B])
Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = E(Gx,Gy)
p = 115792089237316195423570985008687907852837564279074904382605163141518161494337
assert G.order() == p
</code></pre>
<p>Below that portion of the code, you would enter the public key. Then below that is where we extract the signatures.</p>
<p>As the code suggests: "<em># SIGs contains tuples (m, r, s) with (r,s) being a signature for m under P</em>".</p>
<p><strong>How Many Signatures are Needed?</strong></p>
<p>According to recent research published in 2020, titled, '<a target="_blank" href="https://eprint.iacr.org/2020/615.pdf"><strong>LadderLeak</strong>: <em>Breaking ECDSA With Less Than One Bit of Nonce Leakage</em></a>', as its name suggests - <strong>only one bit of nonce leakage is necessary for private key recovery</strong>.</p>
<p>Just in case you didn't know:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932109-3d4b7536-1911-4184-9303-abcc5f26a306.png" alt="image" /></p>
<p>That means if we're able to detect just <strong>one byte of nonce leakage</strong> over 4 signatures (<em>for example</em>), that would be <strong>more than sufficient</strong>. The example post we reference generated 30-40+ signatures (<em>which is</em> <strong>way more than enough</strong>).</p>
<p>As the post notes: "<strong>The...attack works even if nonce have just 1 biased bit, and using some ad-hoc lattices and parameters can work even when only a fraction of a nonce bit is a biased, i.e. is either 0 o;r 1 with probability &gt; 50%</strong>."</p>
<p>Thus, if <strong>any signature generated by these validators has just ONE biased nonce</strong>, then we can successfully recover the private key.</p>
<p><strong>Note</strong>: <em>If you need an online resource for SageMath, then consider using</em> <a target="_blank" href="https://cocalc.com">CoCalc</a></p>
<h3 id="heading-aggregating-signatures-on-avalanche">Aggregating Signatures on Avalanche</h3>
<p>First, we're going to go check out the documentation that Avalanche has on their validators.</p>
<p>You can <a target="_blank" href="https://docs.avax.network/apis/avalanchego/apis/p-chain">find that here</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932118-0e1a7345-e51f-45f5-8f77-6efe31d11c10.png" alt="image" /></p>
<p>We're going to manipulate the many endpoints provided by Avalanche API to aggregate a number of signatures from a particular validator on the chain. For that, we're going to go <a target="_blank" href="https://avascan.info">check out avascan</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932121-f43c6361-3676-4adc-bb65-d7ff5a617fda.png" alt="image" /></p>
<p>The total list of validators <a target="_blank" href="https://avascan.info/staking/validators">can be found here</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932146-22927276-118b-4cae-8b84-1e5f68b9ed75.png" alt="image" /></p>
<p>For convenience, let's go ahead and sort the validator list to show us validators in order by the total amount of $AVAX they have staked (<em>in descending order; that means the validators with the most $AVAX will be listed at the top</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932148-40c00472-e334-4353-8f13-54ce4574714d.png" alt="image" /></p>
<p>Let's see what that list pulls back for us on the block explorer.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932151-3f26b0e2-bdc4-4b5a-b5d9-d6b7712140e1.png" alt="image" /></p>
<p>From what we can see above, none of these validators (<em>shown in the screenshot</em>), are likely to be viable candidates because they don't have any delegates.</p>
<p>However, if we scroll further down the list, we'll find some <strong>ample candidates</strong> that are staking just under the 3 million $AVAX limit.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932156-bab1ab88-e11c-4ce7-8b5b-2fa5b4877e0d.png" alt="image" /></p>
<p><em>How much is that in USD value?</em></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932160-abd3840b-48ec-455a-a9ee-3a7be6d0537a.png" alt="image" /></p>
<p>At the time of writing, the project boasts a $6 billion+ valuation, with each $AVAX token trading for $19.57 a piece at the time of writing.</p>
<p>Quick math tells us that 2.9 million of these tokens represent an approximate value of $50,468,975.15.</p>
<p>Among this list, we only need to choose one candidate. Let's opt for <strong>NodeID-D5yA7HbEr8AJ4yzwVZXsDtb4xhKkTRz73</strong>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932164-dead1a76-9fdb-458f-8505-d9c77d8bfd33.png" alt="image" /></p>
<p>For the purposes of this theoretical example, we chose this vaildator because it has <strong>tons of transactions that can be scraped</strong>.</p>
<p>Moving forward, let's see if we can't aggregate more information about this validator.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932167-696f9505-00a2-4ba2-9107-ed6baeb6a1cf.png" alt="image" /></p>
<p>We can see its beneficiary address is: P-avax1j3mllmr3a54pc9px37pc7fn4ekc9wuwuuf0lz3</p>
<p>If we visit the Avalanche subnet explorer, <a target="_blank" href="https://subnets.avax.network/validators/NodeID-D5yA7HbEr8AJ4yzwVZXsDtb4xhKkTRz73">we can view more information about this particular validator</a>.</p>
<p>From here, we're going to swap over to the X Chaint o glean more information about this asset. To expedite this search, I'm going to just take you straight to a TX of interest, which <a target="_blank" href="https://explorer-xp.avax.network/tx/pJqTd6At5pKhBFmDvvaEfji2oYWqKpzZMrtaCvVxVLhH8Qhyu">you can find here</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932182-d36efa70-e34a-478b-8ac9-049435437a70.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932186-d3e63500-88a2-4432-9467-fd90a2555217.png" alt="image" /></p>
<p>From this TX alone, we can find two different relevant signatures:</p>
<ul>
<li><p>tiAQL+agsAV6EKPX7omdL41Ugzvzta9sLGsQREYPQYYR98wCviQwm2d7qipbgsQsdNqTLq716uyNfCtx3BwNswA=&gt;</p>
</li>
<li><p>32otPdTjtKceXl3NKJCq89zRFY/36RfA9VGAmO9tnZJUEcBi7he3QeDfjXyaXH7ziv8ryFOO6UNuywNXPLKzfQE=&gt;</p>
</li>
</ul>
<p>Here's another <a target="_blank" href="https://explorer-xp.avax.network/tx/VvZBqhPgNJP2sL4okmRMxRgitXKua5AkE8cM7qExz2fnfYtFt">TX of interest</a>:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932195-bfc6331c-0315-48db-bc7a-4212752f1dd1.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932204-875ae18a-0217-4c8e-b591-0611b3be7864.png" alt="image" /></p>
<ul>
<li><p>BXQU15VUZG5tW7PlHwpqzFcxTuwNegVeRohLFrUxrhVqEJSYlG1Nr9RgUsCCiltjvzkGBQbXKI77C5btYpEXPQA=&gt;</p>
</li>
<li><p>PrXlD5Z3CP1ifBS3LctG5OvH6OC7EG7MaDdS3kPCCX5nodttkCveAzjCMmFx8HehxItTl/LW2PhH7TFtsKr5lgE=&gt;</p>
</li>
</ul>
<p>Again, <a target="_blank" href="https://explorer-xp.avax.network/tx/wpWYZFTuSBdaPMb71AsqfY4EZvJBYBj8zJ1tu8xyp851Vzqm6">another one</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219932208-26406bea-2869-4bfb-b120-f5adfdc2db88.png" alt="image" /></p>
<ul>
<li>AnxV6hF/aT8oqGwsHjzaIfqt3d+g1X+AHZI8nikLnDVCUo7FZzsTTPVxi/ZCW6j9jNvwrCgJ4S6bvA1dgA+/tAA=&gt;</li>
</ul>
<p><strong>In total, the signatures we were able to briefly scrape here are</strong></p>
<ol>
<li><p>tiAQL+agsAV6EKPX7omdL41Ugzvzta9sLGsQREYPQYYR98wCviQwm2d7qipbgsQsdNqTLq716uyNfCtx3BwNswA=&gt;</p>
</li>
<li><p>32otPdTjtKceXl3NKJCq89zRFY/36RfA9VGAmO9tnZJUEcBi7he3QeDfjXyaXH7ziv8ryFOO6UNuywNXPLKzfQE=&gt;</p>
</li>
<li><p>BXQU15VUZG5tW7PlHwpqzFcxTuwNegVeRohLFrUxrhVqEJSYlG1Nr9RgUsCCiltjvzkGBQbXKI77C5btYpEXPQA=&gt;</p>
</li>
<li><p>PrXlD5Z3CP1ifBS3LctG5OvH6OC7EG7MaDdS3kPCCX5nodttkCveAzjCMmFx8HehxItTl/LW2PhH7TFtsKr5lgE=&gt;</p>
</li>
<li><p>AnxV6hF/aT8oqGwsHjzaIfqt3d+g1X+AHZI8nikLnDVCUo7FZzsTTPVxi/ZCW6j9jNvwrCgJ4S6bvA1dgA+/tAA=&gt;</p>
</li>
</ol>
<p>We've already gathered 5 addresses here, which should represent a reasonable start for any hacker/bad actor interested in experimenting with the LLL attack on the blockchain.</p>
<p>If there aren't enough signatures in this sample, then there are certainly other validators and accompanying transactions that can be extracted in order to sufficiently test the LLL attack. Taking the effort to scrape said transactions is outside of the scope of this report.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Not paying me a bug bounty is one issue. That makes Avalanche a bunch of assholes, sure. But not paying me and not fixing it? What the fuck is up w that? Since they refuse to address this problem, this should be considered a backdoor.</p>
<h3 id="heading-non-technical-explanation-for-how-curious-this-issue-is">Non-Technical Explanation for How Curious This Issue is</h3>
<p>It’s really hard to find valid code that employs secp256k1 in 2023 that doesn’t properly craft signatures.</p>
<p>For reference, the Bitcoin source code accounts for this properly. Ethereum’s source accounts for this properly (virtually all popular ETH repos used for crafting signatures do; goethereum, eth-sign, foundry, etc.).</p>
<p>The library that Avalanche’s Go code pulls from (Decred), includes the necessary functions to deploy this properly. The Avalanche team could’ve literally copy/pasted their code to fix this.</p>
<p>What’s astounding is they’ve included everything necessary for sig generation EXCEPT for the proper nonce generation. They don’t have the BLS signatures properly deployed (debugged those files, they run back several errors).</p>
<h3 id="heading-this-is-not-an-edge-case-niche-issue">This is Not an “Edge Case” Niche Issue</h3>
<p>This idea of recovering private keys may seem complex to some, which can lead to the mentality that what I'm describing here is some rare, edge case never-would-happen-in-real-life type of vulnerability (not to sound condescending; this is high-level math at the end of the day).</p>
<p>But that could not be further from the truth.</p>
<p>This attack vector that Avalanche has left open has been known for years and there is EXTENSIVE literature, research, etc. that documents the catastrophic impact of improper signature generation.</p>
<h4 id="heading-some-examples-of-past-compromises-and-exploits">Some Examples of Past Compromises and Exploits</h4>
<ol>
<li><p>Remember when Sony got hacked back in 2010 and basically all their user data, games etc got leaked + the master key they were using? Yeah, that was this flaw: <a target="_blank" href="https://www.bbc.co.uk/news/technology-12116051.amp">https://www.bbc.co.uk/news/technology-12116051.amp</a></p>
</li>
<li><p>You guys know “Trail of Bits”? They’re a huge auditor for smart contracts &amp; crypto in this space. Well-respected, yadda yadda. They published an in-depth breakdown about this very issue in 2020 (well worth the read): <a target="_blank" href="https://blog.trailofbits.com/2020/06/11/ecdsa-handle-with-care/">https://blog.trailofbits.com/2020/06/11/ecdsa-handle-with-care/</a></p>
</li>
<li><p>An entire paper published in 2019 where researchers literally crack hundreds of Bitcoin, Ethereum &amp; Ripple (latter is curious since they use ed25519 not secp256k1) wallets: <a target="_blank" href="https://eprint.iacr.org/2019/023.pdf">https://eprint.iacr.org/2019/023.pdf</a></p>
</li>
<li><p>This person purposefully crafted two transactions on Ethereum that were signed using the same nonce. He wanted to see if any attackers would notice and take his funds. Within 24 hours, all the funds in the wallet were drained (this matches what researchers have found, which is that there are already people out there scanning the blockchain for improperly formed signatures so they can recover the private key &amp; drain the wallet of funds) - <a target="_blank" href="https://bertcmiller.com/2021/12/28/glimpse_nonce_reuse.html">https://bertcmiller.com/2021/12/28/glimpse_nonce_reuse.html</a></p>
</li>
<li><p>This is an in-depth guide illustrating how hundreds of Bitcoin private keys were trivially cracked on Bitcoin's blockchain using nothing but the signatures (this link includes hundreds of private keys &amp; a list of transactions + tx data like opcodes &amp; redeem scripts + a very detailed explanation of how these keys were recovered + the revelation that funds were already siphoned from these addresses) - <a target="_blank" href="https://strm.sh/studies/bitcoin-nonce-reuse-attack/">https://strm.sh/studies/bitcoin-nonce-reuse-attack/</a></p>
</li>
</ol>
<p><strong>"You Have to be Some Sort of Expert Programmer or Coding Genius to Exploit This Then, Right?"</strong></p>
<p>No!</p>
<p>In addition to (or in conjunction) with the resources published above, there are also the following code repos and guides for recovering private keys in this manner.</p>
<ol>
<li><p>Simple python script for recovering private keys from signatures that reuse the same nonce - <a target="_blank" href="https://github.com/bytemare/ecdsa-keyrec">https://github.com/bytemare/ecdsa-keyrec</a></p>
</li>
<li><p>Another repo with a simple python script showing you how (just input the values &amp; run it!) - <a target="_blank" href="https://github.com/Marsh61/ECDSA-Nonce-Reuse-Exploit-Example/blob/master/Attack-Main.py">https://github.com/Marsh61/ECDSA-Nonce-Reuse-Exploit-Example/blob/master/Attack-Main.py</a></p>
</li>
<li><p>Another great simple repo (this user has some awesome solidity-based repos) - <a target="_blank" href="https://github.com/tintinweb/ecdsa-private-key-recovery">https://github.com/tintinweb/ecdsa-private-key-recovery</a></p>
</li>
<li><p>For recovering Bitcoin private keys specifically - <a target="_blank" href="https://github.com/daedalus/bitcoin-recover-privkey">https://github.com/daedalus/bitcoin-recover-privkey</a></p>
</li>
<li><p>Recovering ethereum private keys when nonce is generated by concatenating private key + hash(message) [this is what avalanche does] = <a target="_blank" href="https://github.com/jonasnick/ecdsaPredictableNonce">https://github.com/jonasnick/ecdsaPredictableNonce</a></p>
</li>
<li><p>Cracking ECDSA with LLL attacks - <a target="_blank" href="https://github.com/daedalus/BreakingECDSAwithLLL">https://github.com/daedalus/BreakingECDSAwithLLL</a></p>
</li>
<li><p>That trailofbits article has example code - <a target="_blank" href="https://blog.trailofbits.com/2020/06/11/ecdsa-handle-with-care/">https://blog.trailofbits.com/2020/06/11/ecdsa-handle-with-care/</a></p>
</li>
</ol>
<h3 id="heading-final-word">Final Word</h3>
<p>Let Avalanche forever exist as a case study in sheer stupidity, arrogance and apathy. Sincere apologies to anyone that sunk their money into this scam.</p>
]]></content:encoded></item><item><title><![CDATA[Avalanche Protocol Signature Exploit: Part Three]]></title><description><![CDATA[Responding to the Avalanche team's internal report that they sent back to me after the first two reports I submitted to them on February 14th & 15th, 2023. For those curious, that report was published in the Librechain Telegram channel. Follow there ...]]></description><link>https://librehash.xyz/avalanche-protocol-signature-exploit-part-three</link><guid isPermaLink="true">https://librehash.xyz/avalanche-protocol-signature-exploit-part-three</guid><category><![CDATA[Avalanche]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Sun, 19 Feb 2023 06:02:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676786490130/f7c1aea4-9070-410d-93ec-92be2b4523f1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>Responding to the Avalanche team's internal report that they sent back to me after the first two reports I submitted to them on February 14th &amp; 15th, 2023. For those curious, that report was published in the</em> <a target="_blank" href="t.me/librehash"><em>Librechain Telegram channel</em></a><em>. Follow there and</em> <a target="_blank" href="twitter.com/librehash"><em>on Twitter</em></a> <em>for more information.</em></p>
</blockquote>
<p>I'll try to keep my responses brief and to the point here so that our dialogue can remain as productive as possible.</p>
<h3 id="heading-avalanchego-signing-logic-review">AvalancheGo Signing Logic Review</h3>
<p>Under this section, you identify the following operations:</p>
<ol>
<li><p><strong>Sign</strong></p>
</li>
<li><p><strong>SignHash</strong></p>
</li>
<li><p><strong>ecdsa.Sign</strong></p>
</li>
<li><p><strong>signRFC6979</strong></p>
</li>
<li><p><strong>secp256k1.NonceRFC6979</strong></p>
</li>
<li><p><strong>rawSigToSig</strong></p>
</li>
</ol>
<p>My first gripe is with this statement here: "<em>The code used for signature generation and verification does not need to be in AvalancheGo to be invoked. Its absence in the source code of AvalancheGo is the standard pattern for calling a function on an external package.</em>"</p>
<p>Semantically, I don't understand it because at face value it sounds like you all are suggesting that code that does not exist can be invoked. However, I'm assuming what is meant here is that the <strong>function does not need to be defined</strong> in AvalancheGo in order for it to be invoked and defined in the same manner as specified in the library from which the command is inherited.</p>
<p>If I'm correct in my interpretation then, yes, we're in agreement here. However, the issue I raised was that <strong>certain functions alluded to weren't called at all in AvalancheGo</strong> (<em>much less defined anywhere</em>).</p>
<h2 id="heading-ecdsasigncompact">ecdsa.SignCompact</h2>
<p>For some reason, the link referenced here underneath this function points to: <a target="_blank" href="https://github.com/decred/dcrd/blob/9408498fd00555dd268e4987e5c89cd53ab9051f/dcrec/secp256k1/ecdsa/signature.go#L755-L780">https://github.com/decred/dcrd/blob/9408498fd00555dd268e4987e5c89cd53ab9051f/dcrec/secp256k1/ecdsa/signature.go#L755-L780</a></p>
<p>However, <strong>that is not where the library is inherited from</strong>.</p>
<p>The library used in <code>secp256k1r.go</code> inherits from: <a target="_blank" href="https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa">https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa</a></p>
<blockquote>
<p><em>Note if you remove the</em> <a target="_blank" href="https://pkg.go.dev/"><code>https://pkg.go.dev/</code></a> <em>portion of the URL, you are left with the package name, which is</em> <a target="_blank" href="http://github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa"><code>github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa</code></a></p>
</blockquote>
<p>The AvalancheGo code is even shown among the list of importers of this library on the Go pkg site.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219931584-12747a0a-ac80-457a-bed9-75511f9e8c98.png" alt="image" /></p>
<p>In the <code>ReadMe</code>, it's noted that the library, "<em>supports a custom 'compact' signature format which allows efficient recovery of the public key from a given valid signature and message hash combination</em>".</p>
<p>The function in question referenced here (<code>SignCompact</code>), is defined <strong>in full here</strong>:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219931593-4ae5a959-41dc-41dd-b68e-8f3df70ac12f.png" alt="image" /></p>
<p>Specifically, the library defines the function as: <code>func SignCompact(key *secp256k1.PrivateKey, hash []byte, isCompressedKey bool) []byte</code></p>
<p>As stated in the library, this function is defined as follows:</p>
<blockquote>
<p>"<code>SignCompact</code> <em>produces a compact ECDSA signature over the secp256k1 curve for the provided hash (which should be the result of hashing a larger message) using the given private key. The isCompressedKey parameter specifies if the produced signature should reference a compressed public key or not.</em>"</p>
</blockquote>
<p>In the notes that you all passed back to me, you all referenced code located here: <a target="_blank" href="https://github.com/decred/dcrd/blob/9408498fd00555dd268e4987e5c89cd53ab9051f/dcrec/secp256k1/ecdsa/signature.go#L755-L780">https://github.com/decred/dcrd/blob/9408498fd00555dd268e4987e5c89cd53ab9051f/dcrec/secp256k1/ecdsa/signature.go#L755-L780</a></p>
<p>The <strong>only thing that</strong> <code>secp256k1r.go</code> <strong>inherits is the function signature from the library</strong>. The values that are passed to that signature in another piece of code (not referenced in the Avalanche file in question).</p>
<p>For coherency purposes, I'm going to briefly walk down what the Decred code does (<em>replacing their code notes with mine</em>).</p>
<pre><code class="lang-golang"><span class="hljs-comment">// this code iterates the SignCompact function as defined in the library</span>
<span class="hljs-comment">// the variables "key *secp256k1.PrivateKey", "hash []byte", and "isCompressedKey bool" are </span>
<span class="hljs-comment">// all arguments passed to the function</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">SignCompact</span><span class="hljs-params">(key *secp256k1.PrivateKey, hash []<span class="hljs-keyword">byte</span>, isCompressedKey <span class="hljs-keyword">bool</span>)</span> []<span class="hljs-title">byte</span></span> {
    sig, pubKeyRecoveryCode := signRFC6979(key, hash)
    <span class="hljs-comment">// the code above is assigning 'key' and 'hash' (of function signRFC6979) to 'sig' and 'pubKeyRecoveryCode'</span>
    <span class="hljs-comment">// both 'sig' is re-defined using short variable declaration along with 'pubKeyRecoveryCode' </span>
    <span class="hljs-comment">// the only way to derive a valid value for sig in the decred construction is for `signRFC6979` to be</span>
    <span class="hljs-comment">// defined, which it isn't in the AvalancheGo code. This code in decred is only defining the value</span>
    <span class="hljs-comment">// of these variables at RUNTIME and within the function (not globally)</span>
    compactSigRecoveryCode := compactSigMagicOffset + pubKeyRecoveryCode
    <span class="hljs-comment">// code above initializes "compactSigRecoveryCode" variable as the concatenation of </span>
    <span class="hljs-comment">// compactMagicOffset and pubKeyRecoveryCode (the latter we just defined in the prev line)</span>
    <span class="hljs-keyword">if</span> isCompressedKey {
        compactSigRecoveryCode += compactSigCompPubKey
    }
    <span class="hljs-comment">// code above dictates that if the boolean for "isCompressedKey" is true or '1'</span>
    <span class="hljs-comment">// then compactSigRecoveryCode becomes "compactSigRecoveryCode+compactSigCompPubKey"</span>
    <span class="hljs-comment">// ... (remainder of code redacted for brevity sake)</span>
}
</code></pre>
<p>The misunderstanding here on Avalanche dev's end seems to be in the assumption that the variables declared within the body of the <code>SignCompact</code> function in Decred's <code>signature.go</code> file (located in a different, non-referenced codebase), is transposable to the <code>SignCompact' fucntion as defined in AvalancheGo's</code> secp256k1r.go` code.</p>
<p>This is not the case. It's also not possible, logical or in line with Golang's code construction (or that of any programming language).</p>
<p>i'm hoping that we're on the same page with this moving forward.</p>
<h2 id="heading-signrfc6979">signRFC6979</h2>
<p>As noted in the Avalanche dev notes, this function is <strong>explicitly only defined in Decred's code</strong> (<code>signature.go</code>). There is no function signature for <code>signRFC6979</code>.</p>
<p>This is defined in the Decred source file that you all reference in your annotations at line 622 as thus:</p>
<pre><code class="lang-golang"><span class="hljs-comment">// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979</span>
<span class="hljs-comment">// and BIP0062 and returns it along with an additional public key recovery code</span>
<span class="hljs-comment">// for efficiently recovering the public key from the signature.</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">signRFC6979</span><span class="hljs-params">(privKey *secp256k1.PrivateKey, hash []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-params">(*Signature, <span class="hljs-keyword">byte</span>)</span></span> {
    privKeyScalar := &amp;privKey.Key
    <span class="hljs-keyword">var</span> privKeyBytes [<span class="hljs-number">32</span>]<span class="hljs-keyword">byte</span>
    privKeyScalar.PutBytes(&amp;privKeyBytes)
    <span class="hljs-keyword">defer</span> zeroArray32(&amp;privKeyBytes)
    <span class="hljs-keyword">for</span> iteration := <span class="hljs-keyword">uint32</span>(<span class="hljs-number">0</span>); ; iteration++ {
        <span class="hljs-comment">// here, the 'k' variable is generated by through the result returned by the </span>
        <span class="hljs-comment">// NonceRFC6979 function of the secp256k1 library which takes in the private key</span>
        <span class="hljs-comment">// and the hash of the message as inputs for the HMAC-SHA256 algorithm </span>
        <span class="hljs-comment">// the result of the HMAC-SHA256 is the value given to 'k' as a variable (initialized); nonce</span>
        k := secp256k1.NonceRFC6979(privKeyBytes[:], hash, <span class="hljs-literal">nil</span>, <span class="hljs-literal">nil</span>, iteration)
        <span class="hljs-comment">// the variables 'sig' and 'pubKeyRecoveryCode' are assigned after the 'sign' function is iterated</span>
        <span class="hljs-comment">// with the 'privKeyScalar', 'k' (nonce we just derived), and 'hash' [all defined within this function]</span>
        <span class="hljs-comment">// are passed to the 'sign' function (lowercase 's' for sign), which is defined in line 548. </span>
        <span class="hljs-comment">// there are a few critical constructions of the 'sign' function in decred's code which are absent from </span>
        <span class="hljs-comment">// the AvalancheGo code construction - but we'll touch on that afterward. </span>
        <span class="hljs-comment">// ultimately, the biggest contribution made to the code via this function is the definition of 's' and 'r'</span>
        sig, pubKeyRecoveryCode, success := sign(privKeyScalar, k, hash)
        k.Zero()
        <span class="hljs-keyword">if</span> !success {
            <span class="hljs-keyword">continue</span>
        }

        <span class="hljs-keyword">return</span> sig, pubKeyRecoveryCode
    }
}
</code></pre>
<p>Under #4 in the 'AvalancheGo Signing Logic Review', you all write: "The comment at the start of the function (which is called in “3) SignCompact”) states that the purpose of the entire function is to 'generate a deterministic ECDSA signature according to RFC 6979'".</p>
<p>I think the issue here is you all are getting a bit too fixated on the idea of the signature being <strong>deterministic</strong> vs. the <strong>validity of the signature produced</strong>.</p>
<p>To be clear, there is no dispute from me that the signatures that AvalancheGo produces are <strong>deterministic</strong> - without a doubt. The issue is that those signatures are not generated in a <strong>secure manner</strong>. The means by which that can be done is facilitated through the handling and generation of the <strong>nonce</strong> that's constructed as part of secp256k1 signature operations.</p>
<p><strong>Ignore the Code Notes for a Second</strong></p>
<p>I know that the code notes above <code>signRFC6979</code> state that it "generates a deterministic ECDSA signature according to RFC 6979...", but that's not what <strong>that function</strong> is specifically purposed for.</p>
<p>Its role in the greater scheme of this scheme we're looking at (in Decred's codebase), is to solicit the <strong>private key</strong> and the <strong>hash</strong> of the message that is to be signed for the purposes of <strong>piping</strong> those two variables into HMAC-SHA256.</p>
<p>As noted in your developer notes returned to me, the specific function responsible for piping inputs into HMAC-SHA256 is <code>NonceRFC6979</code>. The inclusion of the <code>NonceRFC6979</code> function within the body of the <code>signRFC6979</code> function <strong>is not the default behavior</strong>. Specifically, that function was called to provide a 'short variable declaration' for 'k', which serves as our <strong>nonce value</strong> for the signature operation.</p>
<p>All the <code>NonceRFC6979</code> does (<em>by itself</em>) take inputs (<em>typically private key &amp; message hash plus any other ancillary params &amp; the # of iterations</em>) and pipe them into the HMAC-SHA256 construction. <strong>That's it</strong>.</p>
<p>It is up to the developer/coder to use the 'short variable declaration' feature of Golang to assign the output of this resolution to a variable ('k' in the case of Decred's code). Also, it is the developer's responsibility to ensure that the <strong>function is called explicitly</strong> as <strong>that is the only way the code can specify what values, exactly, we want to pass to that function as an argument</strong>.</p>
<p>To reiterate, those values were derived by the <code>signRFC6979</code> function, which is one <strong>not defined anywhere in any of the imported libraries</strong>. This is a custom, unique function that is defined for the purpose of being iterated <strong>at runtime</strong>.</p>
<p>There's no reason to suggest or propose that this function is iterated <strong>anywhere in the AvalancheGo code</strong>.</p>
<h2 id="heading-secp256k1noncerfc6979">secp256k1.NonceRFC6979</h2>
<p>We've already covered this function (<code>NonceRFC6979</code>) for the most part in the response that I provided above.</p>
<p>The <code>signature.go</code> file for Decred didn't need to define the function since it's derived from one of the imported libraries listed explicitly at the file's header (<em>their secp256k1 Golang library</em>).</p>
<h3 id="heading-none-of-this-code-is-iterated-or-called-in-avalanchego">None of This Code is Iterated or Called in AvalancheGo</h3>
<p>Again, to be clear - this function is neither called nor invoked anywhere in the Avalanche Golang code.</p>
<p>Referring back to the initial function that was referenced (<code>SignCompact</code>), that function is <strong>defined by its corresponding library</strong> (function signature), which has already been pointed out explicitly.</p>
<p>The inclusion of the variable <code>signRFC6979</code> within the body of that function in Decred's codebase (<code>signature.go</code>) has <strong>no bearing or relevance on the code in AvalancheGo</strong>.</p>
<p>If anything, that Decred file should be used as a blueprint for proper implementation that AvalancheGo can use because it makes it explicitly clear that the compliant signatures we're looking for here do not just generate automatically as it appears Avalanche devs are trying to imply for some reason (<strong>no code on planet earth works this way</strong>).</p>
<h2 id="heading-how-avalanchego-actually-signs-code">How AvalancheGo Actually Signs Code</h2>
<p>We'll start with the <code>Sign</code> function, which is used &amp; defined in AvalancheGo's code is thus:</p>
<pre><code class="lang-golang"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(k *PrivateKeySECP256K1R)</span> <span class="hljs-title">Sign</span><span class="hljs-params">(msg []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-params">([]<span class="hljs-keyword">byte</span>, error)</span></span> {
    <span class="hljs-keyword">return</span> k.SignHash(hashing.ComputeHash256(msg))
}
</code></pre>
<p>All this code above says is:</p>
<ol>
<li><p>Use the private key (newly generated) to perform the <code>Sign</code> function on the 'msg'.</p>
</li>
<li><p>Performing the task outlined in #1 will return the results of the <code>SignHash</code> function (when executed with our private key) on the sha256 hash of the msg.</p>
</li>
<li><p>What we wrote in #2 falls in line with how the <code>Sign</code> function is defined in the actual library, which is: <code>func Sign(key *secp256k1.PrivateKey, hash []byte) *Signature</code>.</p>
</li>
</ol>
<p><strong>Nowhere in AvalancheGo's code is the</strong> <code>NonceRFC6979</code> <strong>construction iterated</strong>.</p>
<p>Also, <strong>yes, it must be specifically called to be iterated</strong> because that output is what's piped into the nonce for the signature operation (<em>no mention of a 'nonce' value at all in the AvalancheGo documentation</em>).</p>
<p>Again, the fact that the signatures are generated deterministically are neither here nor there because the <strong>nonce is what counts in this construction</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Avalanche Protocol Signature Exploit: Part Two]]></title><description><![CDATA[This series includes each report I sent to the Avalanche protocol team detailing a potent zero-day vulnerability in their AvalancheGo implementation that allows for the recovery of private keys from signatures formed by nodes & validators. This vulne...]]></description><link>https://librehash.xyz/avalanche-protocol-signature-exploit-part-two</link><guid isPermaLink="true">https://librehash.xyz/avalanche-protocol-signature-exploit-part-two</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 17 Feb 2023 01:48:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676785550384/51ef5144-ff1e-44d5-b0ff-b86cd654459c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>This series includes each report I sent to the Avalanche protocol team detailing a potent zero-day vulnerability in their AvalancheGo implementation that allows for the recovery of private keys from signatures formed by nodes &amp; validators. This vulnerability, which they refuse to patch, allows for</em> <strong>the private keys of validators to be forged</strong>, <em>which essentially renders the entire protocol compromised. If there's anybody out there that's using Avalanche at the time of writing...my best advice as an objective observer and researcher would be to</em> <strong>remove any and all funds you have on this protocol ASAP</strong>.</p>
</blockquote>
<p>Everything below includes what I sent to the Avalanche dev team on HackenProof as a follow-up to the <a target="_blank" href="https://librechain.org/avalanche-protocol-signature-exploit-part-one">initial report I sent to them about this issue</a>. This was sent within 12-24 hours of the first report.</p>
<h1 id="heading-official-report-to-avalanche-developers-part-two">Official Report to Avalanche Developers (Part Two)</h1>
<p>So after taking even more time to look through the code and speak to one of the former developers/maintainers of Avalanche's codebase (<em>and supposed documentation manager as well</em>), I came to a few epiphanies.</p>
<ol>
<li><p>Avalanche's Javascript (avalancheJS) is good to go since it imports from the NPM library, 'ellpitic'. That library specifically notes that "<em>ECDSA is using deterministic</em> <code>k</code> <em>value generation as per</em> <code>RFC 6979</code>. <em>Most of the curve opeartions are performed on non-affine coordinates (either projective or extended), various windowing techniques are used for different cases.</em>" I'd have to go through and check again but I'm pretty sure that this exonerates AvalancheJS entirely (<em>not sure how much this really matters though since the JS library is outside of the scope of what this bug bounty is looking to debug</em>)</p>
</li>
<li><p>The AvalancheGo code <strong>contains references to the proper library</strong>. It just doesn't call the function necessary to ensure that the 'k' is generated deterministically.</p>
</li>
</ol>
<h3 id="heading-secpk1rgo">secpk1r.go</h3>
<p>One file in particular in your Golang codebase is responsible for governing its implementation of secpk1.</p>
<p>That would be <code>avalanchego/utils/crypto/secp256k1r.go</code>, <a target="_blank" href="https://github.com/ava-labs/avalanchego/blob/45ec88151f8a0e3bca1d43fe902fd632c41cd956/utils/crypto/secp256k1r.go">located here</a>.</p>
<p>In the header of that file are two meaningful import statements (<em>re-published below for convenience</em>):</p>
<p>A) "<a target="_blank" href="http://github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa">github.com/decred/dcrd/dcrec/secp256k1/v3/ecdsa</a>"</p>
<p>B) secp256k1 "<a target="_blank" href="http://github.com/decred/dcrd/dcrec/secp256k1/v3">github.com/decred/dcrd/dcrec/secp256k1/v3</a>"</p>
<p>Both statements reference the Decred ecdsa/secp256k1 Golang library. We'll zero in on the <a target="_blank" href="https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v3#section-readme">secp256k1 library</a> since that's most relevant to the topic at hand.</p>
<blockquote>
<p><em>Please note that the hyperlink above takes us to v3, not v4</em> (latest iteration), <em>in accordance to where the import statements point</em>.</p>
</blockquote>
<p>The 'homepage' for this Golang package lists the various features &amp; capabilities of its secp256k1 library. Notably, the devs state:</p>
<ul>
<li><p>"<em>Package secp256k1 implements optimized secp256k1 elliptic curve operations.</em>"</p>
</li>
<li><p>"<em>Specialized types for performing optimized and constant time field operations</em>; <code>FieldVal</code> <em>type for working modulo the secp256k1 field prime</em>" and "<code>ModNScalar</code> <em>type for working modulo the secp256k1 group order</em>"</p>
</li>
<li><p>It allows for point addition, point doubling, scalar multiplication w arbitrary point, &amp; scalar multiplication w the base point (<em>the latter is worth mentioning since that operation is necessary for us to construct a proper signature proof using</em> <code>secp256k</code>).</p>
</li>
<li><p>"<strong>Nonce generation via RFC6979 with support for extra data and version information that can be used to prevent nonce reuse between signing algorithms.</strong>"</p>
</li>
</ul>
<p>The last feature quoted above is the most relevant here for obvious reasons. When I saw that statement, I initially thought that this bug bounty was dead in the water.</p>
<p>However, upon closer examination of this particular library, I noticed that there was a <strong>specific function</strong> set aside and defined to ensure deterministic 'k' (<em>nonce</em>) generation for ECDSA (<code>secp256k1</code>) in accordance with RFC-6979.</p>
<h3 id="heading-function-noncerfc6979">Function NonceRFC6979</h3>
<p><img src="https://user-images.githubusercontent.com/59129716/219527656-2f588c63-ef4c-4b60-ac58-1f0ca36d2713.png" alt="image" /></p>
<p>As shown above, the function is defined as: <code>func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte, extraIterations uint32) *ModNScalar</code>.</p>
<p>The library's authors note that "<em>NonceRFC6979 generates a nonce deterministically according to</em> <code>RFC 6979</code> <em>using</em> <code>HMAC-SHA256</code> <em>for the hashing function. It takes a 32-byte hash as an input and returns a 32-byte nonce to be used for deterministic signing. The extra and version arguments are optional, but allow additional data to be added to the input of the HMAC. When provided, the extra data must be 32-bytes and version must be 16 bytes or they will be ignored.</em>"</p>
<p><strong>Func NonceRFC6979 Absent From the Code</strong></p>
<ol>
<li><p>Nowhere in any of Avalanche's .go files is this function iterated.</p>
</li>
<li><p>Decred's secp256k1 library is the only one imported by Avalanche in their Golang codebase that's equipped to adequately serve as a library for the implementation of secp256k1. Within this library, the aforementioned function (<code>NonceRFC6979</code>), is the only function within it that provisions for the creation of deterministic 'k' (<em>nonces</em>) values in accordance with RFC-6979 for secp256k1 signatures.</p>
</li>
<li><p>The prior two statements being true means that there is <strong>nowhere in the code where</strong> <code>RFC-6979</code> <strong>deterministic k nonces are provisioned</strong>.</p>
</li>
</ol>
<p>That last factual statement iterated in #3 means that there is <strong>no secure means of generating the 'k' nonce for signature operations in Avalanche's Golang codebase</strong> because there are <strong>no other known secure means of generating the 'k' value outside of the specification outlined in RFC-6979 for</strong> <code>secp256k1</code>.</p>
<p>Therefore, whether a 'PoC' is provided or not, it should be considered virtually irrefutable that user private keys are <strong>likely</strong> at grave risk- even if the community is not suffering from widespread theft just yet. That only means that this fact has gone under the radar, which isn't too farfetched if Avalanche's developers made this oversight (<em>that statement is not meant to be sarcastic or insulting in any way; just illuminating the fact that devs as brilliant as the ones working BTS on Avalanche can fail to catch things like this, so how much more likely is it that a random blackhat will notice?</em>).</p>
<h4 id="heading-more-insight-into-the-omission">More Insight into the Omission</h4>
<p>If we take a closer look at the <code>secp256k1</code> library <a target="_blank" href="https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v3#section-readme">provided by Decred</a>, we can see that the function (<code>NonceRFC6979</code>) is defined under a subsection of types called <code>ModNScalar</code>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219527673-8c925aed-9bb2-4805-8256-5f9122040b94.png" alt="image" /></p>
<p>Notably, <strong>only two functions</strong> underneath this subtype of the <code>secp256k</code> library (<code>ModNScalar</code>) is called in the <code>secpk1r.go</code> file.</p>
<p>Those are encompassed at the end of the file between lines 278-289:</p>
<pre><code class="lang-golang"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">verifySECP256K1RSignatureFormat</span><span class="hljs-params">(sig []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">error</span></span> {
    <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(sig) != SECP256K1RSigLen {
        <span class="hljs-keyword">return</span> errInvalidSigLen
    }

    <span class="hljs-keyword">var</span> s secp256k1.ModNScalar
    s.SetByteSlice(sig[<span class="hljs-number">32</span>:<span class="hljs-number">64</span>])
    <span class="hljs-keyword">if</span> s.IsOverHalfOrder() {
        <span class="hljs-keyword">return</span> errMutatedSig
    }
    returun <span class="hljs-literal">nil</span>
}
</code></pre>
<p>Very specifically, I am referring to:</p>
<ol>
<li><p><code>func s.SetByteSlice</code>: "<em>IsOverHalfOrder returns whether or not the scalar exceeds the group order divided by 2 in constant time.</em>" [<code>func (s *ModNScalar) IsOverHalfOrder() bool</code>]</p>
</li>
<li><p><code>func s.SetByteSlice</code>: "<em>SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned integer (meaning it is truncated to the first 32 bytes), packs it into the internal field value representation, and returns whether or not the resulting truncated 256-bit integer is greater than or equal to the field prime (aka it overflowed) in constant time.</em>" [<code>func (f *FieldVal) SetByteSlice(b []byte) bool</code>]</p>
</li>
</ol>
<p>Otherwise, there are nearly 20 other functions available under this type that are <strong>never called</strong> for some reason.</p>
<p>Conversely - however, almost all defined functions under <code>type PrivateKey</code> and <code>type PublicKey</code> <strong>are iterated somewhere in</strong> <code>secp256k1r.go</code>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219527691-9720e674-4e71-4738-b77d-0546bb596c49.png" alt="image" /></p>
<h3 id="heading-new-suggestions-for-improvement-rectify-the-situation">New Suggestions for Improvement / Rectify the Situation</h3>
<p>All that likely needs to be done is AvalancheGo going back into the code in that file (<code>secpk1r.go</code>), and including functions such as <code>NonceRFC6979</code> to derive a secure, deterministic 'k' nonce value for each message signed using <code>secp256k1</code>.</p>
<p><strong>Points Supporting Why This Change Should be Made</strong></p>
<ul>
<li><p>Its secure</p>
</li>
<li><p>It adheres to SOA and standard for <strong>secure secp256k1 signature generation</strong></p>
</li>
<li><p>Averts the <strong>potential catastrophic loss</strong> of unfathomable proportions in an alternate scenario where <strong>no action</strong> is taken.</p>
</li>
<li><p>There are no tangible 'negatives', 'caveats' or "drawbacks" associated with this upgrade/fix in the way <code>secp256k1</code> is implemented in the code.</p>
</li>
</ul>
<p><strong>Let's Check Out the Current</strong> <code>secp256k1</code> <strong>Avalanche.go's Function for Signatures</strong></p>
<pre><code class="lang-golang"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(k *PrivateKeySECP256K1R)</span> <span class="hljs-title">Sign</span><span class="hljs-params">(msg []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-params">([]<span class="hljs-keyword">byte</span>, error)</span></span> {
    <span class="hljs-keyword">return</span> k.SignHash(hashing.ComputeHash256(msg))
}
</code></pre>
<p><strong>Let's Check Out How Decred's</strong> <code>secp256k1</code> Defines a Function for the Same Activity** (Signature)</p>
<pre><code class="lang-golang"><span class="hljs-keyword">type</span> Signature <span class="hljs-keyword">struct</span> {
    r secp256k1.ModNScalar
    s secp256k1.ModNScalar
}

<span class="hljs-comment">// NewSignature instantiates a new signature given some r and s values.</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewSignature</span><span class="hljs-params">(r, s *secp256k1.ModNScalar)</span> *<span class="hljs-title">Signature</span></span> {
    <span class="hljs-keyword">return</span> &amp;Signature{*r, *s}
}
<span class="hljs-comment">// Might as well serialize the signature while we're here, right?</span>
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(sig *Signature)</span> <span class="hljs-title">Serialize</span><span class="hljs-params">()</span> []<span class="hljs-title">byte</span></span> {
    sigS := <span class="hljs-built_in">new</span>(secp256k1.ModNScalar).Set(&amp;sig.s)
    <span class="hljs-keyword">if</span> sigS.IsOverHalfOrder() {
            sigS.Negate()
    }
...
}

<span class="hljs-comment">// *The* `signature.go` *file for Decred's project includes functions for converting a 'field value' to 'scalar modulo the group order'* (returning a boolean of 0/1 contingent on whether conversion resulted in `overflow`; `0` otherwise)</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fieldToModNScalar</span><span class="hljs-params">(v *secp256k1.FieldVal)</span> <span class="hljs-params">(secp256k1.ModNScalar, <span class="hljs-keyword">uint32</span>)</span></span> {
    <span class="hljs-keyword">var</span> buf [<span class="hljs-number">32</span>]<span class="hljs-keyword">byte</span>
    v.PutBytes(&amp;buf)
    <span class="hljs-keyword">var</span> s secp256k1.ModNScalar
    overflow := s.SetBytes(&amp;buf)
    zeroArray32(&amp;buf)
    <span class="hljs-keyword">return</span> s, overflow
}

<span class="hljs-comment">// *This is the code where the scalar modulo of a group order is converted to a field order* (not even sure what the point of this would be since the prime order of `secp256k` is so close to the value of the `finite field` [$F_p$]) </span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fieldToModNScalar</span><span class="hljs-params">(v *secp256k1.FieldVal)</span> <span class="hljs-params">(secp256k1.ModNScalar, <span class="hljs-keyword">uint32</span>)</span></span> {
    <span class="hljs-keyword">var</span> buf [<span class="hljs-number">32</span>]<span class="hljs-keyword">byte</span>
    v.PutBytes(&amp;buf)
    <span class="hljs-keyword">var</span> s secp256k1.ModNScalar
    overflow := s.SetBytes(&amp;buf)
    zeroArray32(&amp;buf)
    <span class="hljs-keyword">return</span> s, overflow
}
</code></pre>
<p>The most marked difference between the two iterations of Decred's library (<em>Avalanche vs Decred</em>) can be seen in Decred's implementation of the 'sign' function as it accounts for the deterministically random 'k nonce value that this bug report centers around.</p>
<p>Specifically, the Decred <code>signature.go</code> file iterates the function as such (<em>code notes included since that's a feature as well imo</em>):</p>
<pre><code class="lang-golang">    <span class="hljs-comment">// sign generates an ECDSA signature over the secp256k1 curve for the provided</span>
    <span class="hljs-comment">// hash (which should be the result of hashing a larger message) using the given</span>
    <span class="hljs-comment">// nonce and private key and returns it along with an additional public key</span>
    <span class="hljs-comment">// recovery code and success indicator.  Upon success, the produced signature is</span>
    <span class="hljs-comment">// deterministic (same message, nonce, and key yield the same signature) and</span>
    <span class="hljs-comment">// canonical in accordance with BIP0062.</span>
    <span class="hljs-comment">//</span>
    <span class="hljs-comment">// Note that signRFC6979 makes use of this function as it is the primary ECDSA</span>
    <span class="hljs-comment">// signing logic.  It differs in that it accepts a nonce to use when signing and</span>
    <span class="hljs-comment">// may not successfully produce a valid signature for the given nonce.  It is</span>
    <span class="hljs-comment">// primarily separated for testing purposes.</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">sign</span><span class="hljs-params">(privKey, nonce *secp256k1.ModNScalar, hash []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-params">(*Signature, <span class="hljs-keyword">byte</span>, <span class="hljs-keyword">bool</span>)</span></span> {

        <span class="hljs-comment">// Author Note: This next collection of code notes shows how critical the RFC-6979 secp256k1 signature </span>
        <span class="hljs-comment">// construction was for ensuring the soundness of the entire algorithm. Those notes are reposted from here</span>
        <span class="hljs-comment">// --------------------------------------</span>
        <span class="hljs-comment">// "The following is a paraphrased version for reference: </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// G = curve generator </span>
    <span class="hljs-comment">// N = curve order </span>
    <span class="hljs-comment">// d = private key </span>
    <span class="hljs-comment">// m = message </span>
    <span class="hljs-comment">// r, s = signature</span>
    <span class="hljs-comment">// </span>
    <span class="hljs-comment">// 1.) Select random nonce k in [1, N-1] (author's note: notable that this is listed as the FIRST step in</span>
    <span class="hljs-comment">// signature generation by the authors of Decred's secp256k1 library that Avalanche uses)</span>
    <span class="hljs-comment">// 2.) Compute kG (this gives us the 'R' value, which is an x, y coordinate) </span>
    <span class="hljs-comment">// 3.) r = kG.x mod N (kG.x is the x coordinate of the point kG) </span>
    <span class="hljs-comment">// ... Repeat from step 1 if r = 0 </span>
    <span class="hljs-comment">// 4.) e = H(m) </span>
    <span class="hljs-comment">// 5.) s = k^-1(e + dr) mod N [author's note: this is the signature proof right here!]</span>
    <span class="hljs-comment">// ... Repeat from step 1 if s = 0 </span>
    <span class="hljs-comment">// 6. Return (r, s) </span>
    <span class="hljs-comment">// </span>
    <span class="hljs-comment">// This is slightly modified here to conform to RFC6979 and BIP 62 as follows: </span>
    <span class="hljs-comment">// </span>
    <span class="hljs-comment">// A. Instead of selceting a random nonce in step 1, use RFC6979 to generate a deterministic </span>
    <span class="hljs-comment">// nonce in [1, N-1] parameterized by the private key, message being signed, and an iteration count for</span>
    <span class="hljs-comment">// the repeat cases . </span>
    <span class="hljs-comment">// </span>
    <span class="hljs-comment">// B. Negate s calculated in step 5 if it is &gt; N/2. </span>
    <span class="hljs-comment">// ... This is done because both s and its negation are valid signatures (author's ntoe: since 'y' can take on </span>
    <span class="hljs-comment">// either positive/negative values on the elliptic curve) modulo the curve order N, </span>
    <span class="hljs-comment">// so it forces a consistent choice to reduce signature malleability (author's note: love this! </span>
    <span class="hljs-comment">// Decred goes above and beyond here with the additional consideration to modulo the entire proof </span>
    <span class="hljs-comment">// by 'n', which is the prime order of the cyclic subgroup for the curve itself).</span>
    <span class="hljs-comment">// </span>
    <span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Step 1 is performed by the caller. </span>
    <span class="hljs-comment">// </span>
    <span class="hljs-comment">// Step 2. </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// Compute kG</span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// Note that the piont must be in affine coordinates (author's note: this is yet another important consideration)</span>
        k := nonce 
        <span class="hljs-keyword">var</span> kG secp256k1.JacobianPoint
        secp256k1.ScalarBaseMultNonConst(k, &amp;kG)
        kG.ToAffine()

        <span class="hljs-comment">// Step 3.</span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// r = kG.x mod N</span>
        <span class="hljs-comment">// Repeat from step 1 if r = 0 </span>
        r, overflow := fieldToModScalar(&amp;kG.X)
        <span class="hljs-keyword">if</span> r.IsZero() {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>, <span class="hljs-number">0</span>, <span class="hljs-literal">false</span> 
        }

        <span class="hljs-comment">// Since the secp256k1 curve has a cofactor of 1, when recovering the public key from an ECSA</span>
        <span class="hljs-comment">// signature over it, there are four possible candidates corresponding to the following cases: </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// 1) The X coord of the random point is &lt; N and its Y coord even </span>
        <span class="hljs-comment">// 2) The X coord of the random point is &lt; N and its Y coord odd</span>
        <span class="hljs-comment">// 3) The X coord of the random point is &gt;= N and its Y coord even</span>
        <span class="hljs-comment">// 4) The X coord of the random point is &gt;= N and its Y coord odd</span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// Rather than forcing the recovery procedure to check all possibel cases, this creates </span>
        <span class="hljs-comment">// a recovery code that uniquely identifies which of the cases apply by making use of </span>
        <span class="hljs-comment">// 2bits. Bit 0 identifies the oddness case and Bit 1 identifies the overlfow case (aka when </span>
        <span class="hljs-comment">// the X coord &gt;= N). </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// It is also worth noting that making use of Hasse's theorem shows there are around </span>
        <span class="hljs-comment">// log_2((p-n/p) ~= -127.65 ~= 1 in 2^127 points where the X coordinate is &gt;= N. It is </span>
        <span class="hljs-comment">// not possible to calculate these points sionce that would require breaking the ECDLP </span>
        <span class="hljs-comment">// but, in practice this strongly implies that with extremely high probability that there</span>
        <span class="hljs-comment">// are only a few actual points for which this case is true.</span>
        pubKeyRecoveryCode := <span class="hljs-keyword">byte</span>(overflow&lt;&lt;<span class="hljs-number">1</span>) | <span class="hljs-keyword">byte</span>(kG.Y.IsOddBit())

        <span class="hljs-comment">// Step 4.</span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// e = H(m) </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// Note that this actually sets e = H(m) mod N which is correct since it is only </span>
        <span class="hljs-comment">// used in step 5 which itself is mod N. </span>
        <span class="hljs-keyword">var</span> e secp256k1.ModNScalar 
        e.SetByteSlice(hash) 

        <span class="hljs-comment">// Step 5 with modification B. </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// s = k^-1(e + dr) mod N</span>
        <span class="hljs-comment">// Repeat from step 1 if s = 0 </span>
        <span class="hljs-comment">// s = -s if s &gt; N/2</span>
        kinv := <span class="hljs-built_in">new</span>(secp256k1.ModNScalar).InverseValNonConst(k)
        s := <span class="hljs-built_in">new</span>(secp256k1.ModNScalar).Mul2(privKey, &amp;r).Add(&amp;e).Mul(kinv)
        <span class="hljs-keyword">if</span> s.IsZero() {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">nil</span>, <span class="hljs-number">0</span>, <span class="hljs-literal">false</span>
        }
        <span class="hljs-keyword">if</span> s.IsOverHalfOrder() {
            s.Negate()
    <span class="hljs-comment">// Negating s corresponds to the random point that owuld have been generated by </span>
    <span class="hljs-comment">// -k (mod N), which necessarily has the opposite oddness since N is prime, </span>
    <span class="hljs-comment">// thus flip the pubkey recovery code oddness bit accordingly </span>
        pubKeyRecoveryCode ^= <span class="hljs-number">0x01</span>
    }

        <span class="hljs-comment">// Step 6. </span>
        <span class="hljs-comment">// </span>
        <span class="hljs-comment">// Return (r, s)</span>
        <span class="hljs-keyword">return</span> NewSignature(&amp;r, s), pubKeyRecoveryCode, <span class="hljs-literal">true</span>
    }
        <span class="hljs-comment">// That's not even all; from here the actual RFC6979 signature construction is included in the code</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">signRFC6979</span><span class="hljs-params">(privKey *secp256k1.PrivateKey, hash []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-params">(*Signature, <span class="hljs-keyword">byte</span>)</span></span> {
        privKeyScalar := &amp;privKey.Key
        <span class="hljs-keyword">var</span> privKeyBytes [<span class="hljs-number">32</span>]<span class="hljs-keyword">byte</span>
        privKeyScalar.PutBytes(&amp;privKeyBytes)
        <span class="hljs-keyword">defer</span> zeroArray32(&amp;privKeyBytes)
        <span class="hljs-keyword">for</span> iteration := <span class="hljs-keyword">uint32</span>(<span class="hljs-number">0</span>); ; iteration++ {
            k := secp256k1.NonceRFC6979(privKeyBytes[:], hash, <span class="hljs-literal">nil</span>, <span class="hljs-literal">nil</span>, iteration)

        <span class="hljs-comment">// Steps 2-6.</span>
        sig, pubKeyRecoveryCode, success := sign(privKeyScalar, k, hash)
        k.Zero()
        <span class="hljs-keyword">if</span> !success {
            <span class="hljs-keyword">continue</span>
        }

        <span class="hljs-keyword">return</span> sig, pubKeyRecoveryCode
    }
    <span class="hljs-comment">// All the code is concluded with the following sign function</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">Sign</span><span class="hljs-params">(key *secp256k1.PrivateKey, hash []<span class="hljs-keyword">byte</span>)</span> *<span class="hljs-title">Signature</span></span> {
    signature, _ := signRFC6979(key, hash)
        <span class="hljs-keyword">return</span> signature
    }
}
</code></pre>
<h3 id="heading-decreds-signature-verification-more-robust-secure-too">Decred's Signature Verification = More Robust + Secure Too</h3>
<p>In addition, Decred's signature verification scheme is more robust than the one currently implemented by Avalanche in their Golang codebase.</p>
<p><strong>Avalanche's Current Go-based Construction for Sig Verification</strong> (<em>from</em> <code>secp256k1r.go</code>)</p>
<pre><code class="lang-golang"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(k *PublicKeySECP256K1R)</span> <span class="hljs-title">Verify</span><span class="hljs-params">(msg, sig []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">bool</span></span> {
    <span class="hljs-keyword">return</span> k.VerifyHash(hashing.ComputeHash256(msg), sig)
}

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(k *PublicKeySECP256K1R)</span> <span class="hljs-title">VerifyHash</span><span class="hljs-params">(hash, sig []<span class="hljs-keyword">byte</span>)</span> <span class="hljs-title">bool</span></span> {
    factory := FactorySECP256K1R{}
    pk, err := factory.RecoverHashPublicKey(hash, sig)
    <span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }
    <span class="hljs-keyword">return</span> k.Address() == pk.Address()
}
</code></pre>
<p><strong>Decred's Iteration of Signature Verification for</strong> <code>secp256k</code> <strong>per Their Project's Specifications</strong></p>
<pre><code class="lang-golang"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(sig *Signature)</span> <span class="hljs-title">Verify</span><span class="hljs-params">(hash []<span class="hljs-keyword">byte</span>, pubKey *secp256k1.PublicKey)</span> <span class="hljs-title">bool</span></span> {
    <span class="hljs-keyword">if</span> sig.r.IsZero() || sig.s.IsZero() {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }

    <span class="hljs-keyword">var</span> e secp256k1.ModNScalar
    e.SetByteSlice(hash)

    w := <span class="hljs-built_in">new</span>(secp256k1.ModNScalar).InverseValNonConst(&amp;sig.s)

    u1 := <span class="hljs-built_in">new</span>(secp256k1.ModNScalar).Mul2(&amp;e, w)
    u2 := <span class="hljs-built_in">new</span>(secp256k1.ModNScalar).Mul2(&amp;sig.r, w)

    <span class="hljs-keyword">var</span> X, Q, u1G, u2Q secp256k1.JacobianPoint
    pubKey.AsJacobian(&amp;Q)
    secp256k1.ScalarBaseMultNonConst(u1, &amp;u1G)
    secp256k1.ScalarMultNonConst(u2, &amp;Q, &amp;u2Q)
    secp256k1.AddNonConst(&amp;u1G, &amp;u2Q, &amp;X)

    <span class="hljs-keyword">if</span> (X.X.IsZero() &amp;&amp; X.Y.IsZero()) || X.Z.IsZero() {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }

    z := <span class="hljs-built_in">new</span>(secp256k1.FieldVal).SquareVal(&amp;X.Z)

    sigRModP := modNScalarToField(&amp;sig.r)
    result := <span class="hljs-built_in">new</span>(secp256k1.FieldVal).Mul2(&amp;sigRModP, z).Normalize()
    <span class="hljs-keyword">if</span> result.Equals(&amp;X.X) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>
    }

    <span class="hljs-keyword">if</span> sigRModP.IsGtOrEqPrimeMinusOrder() {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
    }

    sigRModP.Add(&amp;orderAsFieldVal)
    result.Mul2(&amp;sigRModP, z).Normalize()
    <span class="hljs-keyword">return</span> result.Equals(&amp;X.X)
}

<span class="hljs-comment">// *Also this brief call to an* `IsEqual` *function*</span>

<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(sig *Signature)</span> <span class="hljs-title">IsEqual</span><span class="hljs-params">(otherSig *Signature)</span> <span class="hljs-title">bool</span></span> {
    <span class="hljs-keyword">return</span> sig.r.Equals(&amp;otherSig.r) &amp;&amp; sig.s.Equals(&amp;otherSig.s)
}
</code></pre>
<h2 id="heading-concluding-thoughts-and-suggestions">Concluding Thoughts and Suggestions</h2>
<ol>
<li><p>To me, it seems like a no-brainer to 'copy' over Decred's implementation of secp256k1 since the Avalanche Golang library already imports directly from the project's secp256k1 library as it is. All Avalanche would have to do is update the version for the package they call (<em>from v3 to v4</em>), and adjust the <code>sign</code> and <code>signature</code> functions accordingly (<em>anything beyond that is luxury</em>)</p>
</li>
<li><p>The signature scheme for secp256k1 implemented by Decred (<em>using the same library called on by Avalanche Go</em>) exemplifies the types of changes that Avalanche should look to embrace if they want to secure users from the imminent &amp; likely burgeoning threat that they will have their wallets drained in lieu of this approach. To reiterate what was stated earlier in this 3rd report, the RFC 6979 specification for secure secp256k1 (<em>deterministic</em>) signatures is really the <strong>only</strong> standard that accomplishes such. Thus, there are no other <strong>audited, publicly specified and scrutinized methods for generating secp256k1 signatures that meet the bar</strong>.</p>
</li>
<li><p>While the developers of Avalanche may not necessarily consider this to be a 'bug', I believe that <strong>it absolutely is</strong>. One reason I make this claim is that the library (<strong>Decred's secp256k1</strong>) is referenced in the 'import' function in the header of the <code>secp256k1r.go</code> (Avalanche) file <strong>already contains the RFC 6979 signature specification I've been mentioning</strong>. The actual function as defined by the library just wasn't included in Avalanche's codebase for some reason - which leads me to believe that this was just a mere oversight, mistake, etc., <strong>rather than a purposeful decision by the team</strong>. This deterministic nonce-based signature construction for <code>secp256k1</code> is a <strong>prominent feature</strong> of the Decred secp256k1 library. As we saw from the code excerpts above, it was a <strong>major consideration</strong> that the devs of the library took into account whilst coding the <code>signature.go</code> file of the Decred file.</p>
</li>
</ol>
<p>In my opinion, I believe the Avalanche development team should be in agreement with me that (a) the aforementioned changes in this 3rd report should be implemented at some point in the foreseeable future (b) the current iteration of Avalanche's Golang codebase that's devoid of these proposed changes serves as an existential threat that it poses the threat of <strong>complete compromise and total loss of funds of all those that use it</strong> - either <em>directly or indirectly</em>.</p>
<p>This risk should be seen as unpalatable by the Avalanche dev team. With that being said, I'm not proposing that the team shift into emergency protocol to make sweeping changes to very critical, sensitive pieces of the protocol over night - but given the critical nature of these proposed updates and the <strong>near guarantee</strong> that the pending catastrophic outcome facing Avalanche will be brought to fruition in lieu of affirmative action on this matter, I believe we're all collectively on the same page in our beliefs that <strong>something should be done. Soon</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Avalanche Protocol Signature Exploit: Part One]]></title><description><![CDATA[This series includes each report I sent to the Avalanche protocol team detailing a potent zero-day vulnerability in their AvalancheGo implementation that allows for the recovery of private keys from signatures formed by nodes & validators. This vulne...]]></description><link>https://librehash.xyz/avalanche-protocol-signature-exploit-part-one</link><guid isPermaLink="true">https://librehash.xyz/avalanche-protocol-signature-exploit-part-one</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[Avalanche]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 17 Feb 2023 01:27:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676597209087/7fc7b091-a34f-49d8-8fe7-835acfbf5aef.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>This series includes each report I sent to the Avalanche protocol team detailing a potent zero-day vulnerability in their AvalancheGo implementation that allows for the recovery of private keys from signatures formed by nodes &amp; validators. This vulnerability, which they refuse to patch, allows for</em> <strong>the private keys of validators to be forged</strong>, <em>which essentially renders the entire protocol compromised. If there's anybody out there that's using Avalanche at the time of writing...my best advice as an objective observer and researcher would be to</em> <strong>remove any funds you have on this protocol ASAP</strong>.</p>
</blockquote>
<p>Everything below includes what I sent to the Avalanche dev team on HackenProof in response to their request for more information about this vulnerability. At the bottom of this initial report is a proof of concept where I successfully recover a private key.</p>
<h1 id="heading-official-report-to-avalanche-developers-part-one">Official Report to Avalanche Developers (Part One)</h1>
<blockquote>
<p><em>Pursuant to your request for more information and a reproducible means of exploring this vulnerability/flaw in the design of the signature algorithm, I'm appending this report as an informal "part two" of sorts</em>.</p>
</blockquote>
<p>As a recap, I'll start with the information that I wrote about RFC-6979 deterministic signatures using ecdsa.</p>
<h3 id="heading-walking-through-how-to-create-a-signature-with-ecdsa">Walking Through How to Create a Signature with ECDSA</h3>
<p>In this process, we'll assume that we already have our private key ('x') and public key ('y') [<em>the latter won't be necessary for the formation of the signature</em>].</p>
<p>The other variables as defined for secp256k1 in the <a target="_blank" href="https://www.secg.org/sec2-v2.pdf">secg specification</a> still applies.</p>
<ol>
<li><p><strong>calculate the hash of the message</strong> (<em>sha256 hash algo for consistency</em>): <strong>h = hash(msg)</strong></p>
</li>
<li><p><strong>generate a value for 'k'</strong>: <em>that falls within the range of [1..n-1]</em></p>
</li>
<li><p><strong>derive an x,y coordinate from 'k' the same way we did for 'x'</strong>: R (random point) = $k*G$</p>
</li>
<li><p><strong>take the x-coordinate of 'R'</strong>: $r = R.x$</p>
</li>
<li><p><strong>calculate the signature proof</strong>: $s = k^{-1} <em>(h + r</em> x) (modulo   n)$</p>
</li>
</ol>
<p>The above steps yield a signature, which is represented by the variables (<strong>r, s</strong>), which are:</p>
<ol>
<li><p><strong>x value of the pseudo-pubkey coordinate derived from our ephemeral 'private key' (k)</strong> = r</p>
</li>
<li><p><strong>signature proof itself</strong> = s = ($k^{-1} * (h + (rx)) (modulo   n)$)</p>
</li>
</ol>
<h2 id="heading-getting-to-the-root-of-the-issue-on-avalanche">Getting to the Root of the Issue on Avalanche</h2>
<p>I'm going to go ahead and shift focus from the AvalancheJS codebase and dive into the Avalanche Go code since that's one of the stated focuses of this bug bounty program.</p>
<p>Specifically, I'm going to start with Avalanche's documentation here: <a target="_blank" href="https://docs.avax.network/subnets/create-a-vm-blobvm">https://docs.avax.network/subnets/create-a-vm-blobvm</a></p>
<h3 id="heading-avalanches-documentation-on-transaction-states">Avalanche's Documentation on Transaction States</h3>
<p>Under the first heading titled, 'Transactions', the documentation notes: <em>"The state the blockchain can only be mutated by getting the network to accept a signed transaction. A signed transaction contains the transaction to be executed alongside the signature of the issuer. The signature is required to cryptographically verify the sender's identity. A VM can define an arbitrary amount of unique transaction types to support different operations on the blockchain.</em>"</p>
<p>From there, I'm going to fast forward to the subheading titled, '<em>Signed Transaction</em>. There, the documentation notes, "<em>BlobVM implements signed transactions by embedding the unsigned transaction alongside its signature in</em> <code>Transaction</code>. <em>In BlobVM, a signature is defined as the</em> <code>ECDSA signature</code> <em>of the issuer's private key of the</em> <code>KECCAK256</code> <em>hash of the unsigned transaction's data</em> (<code>digest hash</code>)."</p>
<h4 id="heading-signature-related-documentation-settx">Signature-Related Documentation (<code>SetTx</code>)</h4>
<p>As the documentation notes, in order to issue a <code>SetTx</code> transaction, one starts by composing the unsigned transaction for that type:</p>
<pre><code class="lang-golang">utx := &amp;chain.SetTx{
    BaseTx: &amp;chain.BaseTx{},
    Value:  []<span class="hljs-keyword">byte</span>(<span class="hljs-string">"data"</span>),
}

utx.SetBlockID(lastAcceptedID)
utx.SetMagic(genesis.Magic)
utx.SetPrice(price + blockCost/utx.FeeUnits(genesis))
</code></pre>
<p>The above is not of particular importance. However, what follows is.</p>
<p><strong>Calculating Digest Hash for the TX</strong></p>
<p>This is coded as:</p>
<pre><code class="lang-golang">digest, err := chain.DigestHash(utx)
</code></pre>
<p>From there, the <code>digest</code> (<em>variable created via taking the</em> <code>keccak256</code> <em>of the unsigned TX</em>) is <strong>signed</strong> via the following:</p>
<pre><code class="lang-golang">signature, err := chain.Sign(digest, privateKey)
</code></pre>
<p>Herein lies the issue above.</p>
<h3 id="heading-dissecting-the-issue-with-avalanches-current-construction-in-this-scheme">Dissecting the Issue with Avalanche's Current Construction in This Scheme</h3>
<p>The signature that's created is generated solely by signing the keccak256 hash of the unsigned transaction data.</p>
<p><strong>Combing Through the Remaining Codebase</strong></p>
<p>I have spent the past few hours combing <em>extensively</em> through the Avalanche codebase (<em>specifically for Avalanche Go</em>).</p>
<p>After completing what I can only assume is an exhaustive search (<em>please correct me if I'm wrong</em>) amid other tests and observations, it appears that:</p>
<ol>
<li><p>Avalanche uses secp256k1 (ecdsa) as their algorithm of choice for both generating private &amp; public key pairs and for their signature algorithm as well.</p>
</li>
<li><p>Given #1, it must be true that a 'nonce' value of some sort is generated in order to create a signature (<em>this is part of the secp256k1 specification</em>)</p>
</li>
<li><p>My personal tests have revealed that re-generating a signature with the exact same parameters yields a duplicate output. Thus, the signatures generated with Avalanche Go <strong>have to be deterministic</strong>.</p>
</li>
<li><p><strong>Nowhere in the codebase</strong> does Avalanche stipulate that they have <strong>employed RFC 6979</strong></p>
</li>
<li><p>Given this fact, there must be another source that Avalanche is using to create a <strong>deterministic signature</strong>. The only other one that I can see in the code (<em>or imagine after heavy discussion w other developers</em>) is the actual keccak256 digest of the message (<em>transaction struct</em>) itself.</p>
</li>
</ol>
<p>To be clear, what I'm suggesting is that Avalanche's Go implementation uses the <code>keccak256</code> hash of the transaction data (<em>to be signed</em>) as its source for the 'nonce' that's included as part of the secp256k1 signature algorithm.</p>
<h2 id="heading-why-avalanches-source-for-the-nonce-in-their-signature-algo-is-a-major-problem">Why Avalanche's Source for the Nonce in Their Signature Algo is a Major Problem</h2>
<p>The nonce is supposed to be derived from a <strong>random/pseudo-random source</strong>. In the case of it being deterministic, there are expected pieces of information that are fed into the <strong>HMAC-SHA256</strong> construction in order to abate private key recovery via nonce leakage/usage.</p>
<p>This is because <strong>one potent attack vector</strong> associated with secp256k1 is the fact that <strong>private keys can be recovered if the nonce for more than one signature operation can be determined</strong>.</p>
<h3 id="heading-dangers-of-an-insecure-nonce">Dangers of an Insecure Nonce</h3>
<p>If an insecure nonce is used in secp256k1 signature operations, it may be possible for an attacker to recover the private key used to generate the signature. This is known as a "nonce reuse" attack, and it is a type of side-channel attack that can be used to break the security of the signature scheme.</p>
<p>The basic idea behind a nonce reuse attack is as follows: since the nonce is not being generated randomly and is instead being derived from a known value (such as the message), an attacker may be able to compute the value of the nonce used in a signature by analyzing multiple signatures of different messages that have been signed with the same private key. Once the attacker has determined the value of the nonce, they can use this information to compute the private key used to sign the messages.</p>
<p>The exact method for recovering the private key will depend on the specific implementation of the secp256k1 algorithm, as well as the details of the nonce generation method being used. However, in general, the attack involves using a set of signatures to compute a system of equations that can be solved to recover the private key.</p>
<p>To protect against nonce reuse attacks, it is important to use a secure method for generating nonces in secp256k1 signature operations. The RFC 6979 algorithm is one such method that is designed to generate random and unpredictable nonces for each signature operation, which can help prevent nonce reuse attacks. Additionally, it is important to ensure that the random number generator used to generate the nonce is cryptographically secure and to take other steps to protect against side-channel attacks.</p>
<h3 id="heading-actually-recovering-private-keys-from-reused-nonces">Actually Recovering Private Keys from Reused Nonces</h3>
<p>Substantially more information is <a target="_blank" href="https://blog.trailofbits.com/2020/06/11/ecdsa-handle-with-care/">offered here by 'Trail of Bits'</a>.</p>
<p>However, the gist is that:</p>
<ul>
<li><p>Since ecdsa (secp256k1) signature operations involve providing a signature proof that reads: $s = (k^-1(H(m) + xr)$</p>
</li>
<li><p>We can compute/recover a private key so long as we know the nonce ('k'), by virtue of: $ks = H(m) +x*r$ (<em>assuming 'H(m)' here is the hashed message, 'x' is the private key integer and 'r' is the 'x' value of the x,y coordinate generated by multiplying the curve generator base point times 'k'</em> [$r = kG$])</p>
</li>
<li><p>After we've moved the 'k' over to our equation to create $ks = H(m) + x*r$, we simply subtract the hashed message value (converted to an integer, represented by '<em>H(m)</em>' here), to give us $ks - H(m) = xr$</p>
</li>
<li><p>From there, we derive the private key by simply solving the equation (<em>with our knowledge of 'k'</em>) to give us $x = r^-1*(ks-H(m))$; remember, the 'r' variable is made public (<em>as part of r,s,v</em>) and so is s as well as the hashed message (<em>H(m)</em>), so we're merely plugging in values at this point.</p>
</li>
</ul>
<p><strong>Modules Online That Show Efficient Nonce Recovery for secp256k1</strong></p>
<p>There are several modules online showing such a key recovery.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219524265-2157ec06-27d5-4cc2-ba96-898b211d20c3.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://asecuritysite.com/encryption/ecd3">https://asecuritysite.com/encryption/ecd3</a></p>
</blockquote>
<p><strong>Live Example from Avalanche Docs</strong></p>
<p>Let's go back here: <a target="_blank" href="https://docs.avax.network/specs/cryptographic-primitives">https://docs.avax.network/specs/cryptographic-primitives</a></p>
<p>If we fly down to the part where Avalanche gives its 'Rick and Morty' example, we can extract all of the relevant information <strong>outside of the private key</strong> and still recover the private key.</p>
<p>I actually had to make a few modifications, but I used the same base private key that was provided there: <code>0x98cb077f972feb0481f1d894f272c6a1e3c15e272a1658ff716444f465200070</code></p>
<p>Then I converted that private key to a decimal value (integer) for the purposes of slotting it into a python script.</p>
<p>That value = <code>69110274690866025692964149917516030805802301098524286277666640594465779089520</code></p>
<p>From there, I inputted it into the following python script:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> ecdsa
<span class="hljs-keyword">import</span> random
<span class="hljs-keyword">import</span> libnum
<span class="hljs-keyword">import</span> olll
<span class="hljs-keyword">import</span> hashlib
<span class="hljs-keyword">import</span> sys

<span class="hljs-comment"># https://blog.trailofbits.com/2020/06/11/ecdsa-handle-with-care/</span>

G = ecdsa.NIST256p.generator
order = G.order()
priv = <span class="hljs-number">69110274690866025692964149917516030805802301098524286277666640594465779089520</span>

Public_key = ecdsa.ecdsa.Public_key(G, G * priv)
Private_key = ecdsa.ecdsa.Private_key(Public_key, priv)

k1 = random.randrange(<span class="hljs-number">1</span>, pow(<span class="hljs-number">2</span>,<span class="hljs-number">127</span>))
k2 = random.randrange(<span class="hljs-number">1</span>, pow(<span class="hljs-number">2</span>,<span class="hljs-number">127</span>))

msg1=<span class="hljs-string">"hello"</span>
msg2=<span class="hljs-string">"hello1"</span>

<span class="hljs-keyword">if</span> (len(sys.argv)&gt;<span class="hljs-number">1</span>):
    msg1=(sys.argv[<span class="hljs-number">1</span>])
<span class="hljs-keyword">if</span> (len(sys.argv)&gt;<span class="hljs-number">2</span>):
    msg2=(sys.argv[<span class="hljs-number">2</span>])

m1 = int(hashlib.sha256(msg1.encode()).hexdigest(),base=<span class="hljs-number">16</span>)
m2 = int(hashlib.sha256(msg2.encode()).hexdigest(),base=<span class="hljs-number">16</span>)

sig1 = Private_key.sign(m1, k1)
sig2 = Private_key.sign(m2, k2)

<span class="hljs-keyword">print</span> (<span class="hljs-string">"Message 1: "</span>,msg1)
<span class="hljs-keyword">print</span> (<span class="hljs-string">"Message 2: "</span>,msg2)
<span class="hljs-keyword">print</span> (<span class="hljs-string">"\nSig 1 r,s: "</span>,sig1.r,sig1.s)
<span class="hljs-keyword">print</span> (<span class="hljs-string">"Sig 2 r,s: "</span>,sig2.r,sig2.s)
<span class="hljs-keyword">print</span> (<span class="hljs-string">"\nk1: "</span>,k1)
<span class="hljs-keyword">print</span> (<span class="hljs-string">"k2: "</span>,k2)

<span class="hljs-keyword">print</span> (<span class="hljs-string">"Private key: "</span>,priv)

r1 = sig1.r
s1_inv = libnum.invmod(sig1.s, order)
r2 = sig2.r
s2_inv = libnum.invmod(sig2.s, order)

matrix = [[order, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>], [<span class="hljs-number">0</span>, order, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>],
[r1*s1_inv, r2*s2_inv, (<span class="hljs-number">2</span>**<span class="hljs-number">128</span>) / order, <span class="hljs-number">0</span>],
[m1*s1_inv, m2*s2_inv, <span class="hljs-number">0</span>, <span class="hljs-number">2</span>**<span class="hljs-number">128</span>]]

search_matrix = olll.reduction(matrix, <span class="hljs-number">0.75</span>)
r1_inv = libnum.invmod(sig1.r, order)
s1 = sig1.s

<span class="hljs-keyword">for</span> search_row <span class="hljs-keyword">in</span> search_matrix:
    possible_k1 = search_row[<span class="hljs-number">0</span>]
    try_private_key = (r1_inv * ((possible_k1 * s1) - m1)) % order

    <span class="hljs-keyword">if</span> ecdsa.ecdsa.Public_key(G, G * try_private_key) == Public_key:
        print(<span class="hljs-string">"\nThe private key has been found"</span>)
        <span class="hljs-keyword">print</span> (try_private_key)
</code></pre>
<p>Then I ran it in repl.</p>
<p>This enabled me to <strong>successfully recover the private key</strong> with just two different known messages (and accompanying signatures, in theory):</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219524603-36693742-edb4-4e70-b2bc-0a7e178a4e57.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219524611-d472f561-bd2f-46aa-abe7-71a8d1ad4d07.png" alt="image" /></p>
<p>To do so, I <a target="_blank" href="https://asecuritysite.com/ecc/ecd">used this module on 'asecuritysite'</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219524621-2a461c75-b403-401d-9738-24d39cebe542.png" alt="image" /></p>
<p>In essence, what this module shows is that with the revelation of a 'k value' (for either one of the messages being hashed), the private key can be successfully recovered.</p>
<p>Of course, in this case, the private key value was plugged in ahead of time - but that's only so we're able to evaluate whether the finally generated private key matches our input or not (<em>denoted by the congratulatory message at the end</em>).</p>
<p>Please let me know if there are any further questions!</p>
]]></content:encoded></item><item><title><![CDATA[$MATIC = Great Long-Term Position]]></title><description><![CDATA[Without wasting any time here, we're going to start on the daily resolution and look at the trajectory of Polygon's price action over time.
Specifically, we're going to start by drawing an overhead diagonal downtrend resistance from the previous loca...]]></description><link>https://librehash.xyz/matic-great-long-term-position</link><guid isPermaLink="true">https://librehash.xyz/matic-great-long-term-position</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Thu, 16 Feb 2023 18:58:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676573826909/ab412102-0b7e-4378-be0c-f01967a0c3b5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Without wasting any time here, we're going to start on the daily resolution and look at the trajectory of Polygon's price action over time.</p>
<p>Specifically, we're going to start by drawing an overhead diagonal downtrend resistance from the previous localized high, which occurred in late December 2021.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460139-f0cf23ec-9416-43c3-b4c7-e8eb3d3ce03b.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/CK35lVU9/">https://www.tradingview.com/x/CK35lVU9/</a></p>
<p><strong>Why are We Doing This?</strong></p>
<p>To give us a sense for when the price <strong>broke out</strong> from this overhead diagonal downtrend resistance.</p>
<p>If we look closely (on the daily resolution, still), we can see where $Matic broke above this overhead diagonal downtrend resistance circa mid-2022.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460164-371c6d6b-08d2-425b-8d36-94ae5a4ea82d.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/2knhEggM/">https://www.tradingview.com/x/2knhEggM/</a></p>
<p>Let's check out the price trajectory from that point in mid-2022 to present.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460285-06bdf9c2-b13b-4816-ab2e-af798fa6ee9f.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/gMnErrKB/">https://www.tradingview.com/x/gMnErrKB/</a></p>
<p>As we can see from the chart above, Matic has posted a +50% ROI dating back to that point in late July 2022.</p>
<p>This is in stark contrast with the overall market performance from that point to present (<em>specifically Bitcoin and Ethereum</em>).</p>
<p><strong>Bitcoin's Performance</strong></p>
<p>Below is a look at the net change in price for Bitcoin over the same span of time (July 2022 - present).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460305-6de1176f-010a-43a4-9005-8dddafced775.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/3Q8bmvnk/">https://www.tradingview.com/x/3Q8bmvnk/</a></p>
<p><strong>Ethereum's Performance</strong></p>
<p>Below is a look at the net change in price for Ethereum over the same span of time (July 2022 - Present).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460319-1425b64b-cc4c-42c9-b353-001bef4f9edc.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/rwianFsI/">https://www.tradingview.com/x/rwianFsI/</a></p>
<p><strong>Takeaways</strong></p>
<p>Its worth noting that the above observations are only meant to serve as hasty comparisons to Matic's price action over the same span of time to exemplify the standout performance of this token over the past 6-7 months.</p>
<p><strong>Piecing it All Together</strong></p>
<p>Beyond noting that Matic's price action has been markedly more bullish than Bitcoin or Ethereum (<em>both chosen as benchmarks given their market share % and corresponding 'weight' in influencing prevailing market trend and trajectory</em>), its also worth observing:</p>
<ol>
<li><p>For the vast majority of the period observed (July 2022 - Feb 2023) for Bitcoin and Ethereum, the price of both assets traded below the assets' close price on July 27th, 2022.</p>
</li>
<li><p>Contrary to the observation made in #1, Matic has spent almost as much time <strong>above</strong> its close on July 27th, 2022 as it did below.</p>
</li>
</ol>
<h3 id="heading-notable-recent-price-action">Notable Recent Price Action</h3>
<p>Let's take another look at Matic on the daily resolution.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460340-2a3c94e7-8eb5-417e-b0f6-80a6a1ee5e59.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/VeCguDaT/">https://www.tradingview.com/x/VeCguDaT/</a></p>
<p>As we can see in the chart above, from August 2022 to January 14th, 2023, Matic's price consistently failed to break above the 94 cent realm.</p>
<p>There's one notable exception where the price of Matic broke above this overhead horizontal resistance briefly from November 3th-12th, 2022.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460366-1e3b84c7-db6d-4f23-85ad-5af777cea120.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/v1rnVplQ/">https://www.tradingview.com/x/v1rnVplQ/</a></p>
<p>As noted in the chart above, that breakout was spurred on by the SBF implosion that took place around that same time.</p>
<p>Notably, the implosion of FTX and Alameda put the existential fate of Solana (as both a project and ecosystem) into serious question since SBF and Alameda were both seen as the primary driving forces fueling the project's growth and sustainability.</p>
<p>Thus, when the SBF situation grew increasingly volatile and catastrophic, investors bought Matic anticipating that impending consequences for Solana would lead to an increased market share and prominence for the competitor.</p>
<p>As the chart above also shows, this sentiment was short-lived as the price of Matic dipped back down below the overhead horizontal resistance at 94 cents.</p>
<h4 id="heading-recent-breakout">Recent Breakout</h4>
<p>This most recent breakout in price for $Matic should be considered 'legit'.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219460387-387682e4-df80-452c-b8bf-2336af2ad484.png" alt="image" /></p>
<p><a target="_blank" href="https://www.tradingview.com/x/l1fgMlcM/">https://www.tradingview.com/x/l1fgMlcM/</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We're going to make this one of our long-term positions (as mentioned in the Discord). Let's see how this trade pans out over the next quarter or two.</p>
]]></content:encoded></item><item><title><![CDATA[Ethereum Price Outlook - Feb 15th 2023]]></title><description><![CDATA[Given the recent price action of Ethereum and the markets, it seemed reasonable to check out how the asset's been doing lately - especially since the price of $ETH is rubbing against a long-term overhead horizontal resistance.
Ethereum on the Daily R...]]></description><link>https://librehash.xyz/ethereum-price-outlook-feb-15th-2023</link><guid isPermaLink="true">https://librehash.xyz/ethereum-price-outlook-feb-15th-2023</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Thu, 16 Feb 2023 00:26:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676507146198/c6efbcac-db29-4bf1-8ea6-86004db4f958.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://user-images.githubusercontent.com/59129716/219225630-3da4c95a-1069-41eb-b9a9-31715a243b7d.gif" alt="ethcodedesign" /></p>
<p>Given the recent price action of Ethereum and the markets, it seemed reasonable to check out how the asset's been doing lately - especially since the price of $ETH is rubbing against a long-term overhead horizontal resistance.</p>
<h3 id="heading-ethereum-on-the-daily-resolution">Ethereum on the Daily Resolution</h3>
<p><img src="https://user-images.githubusercontent.com/59129716/219225650-f27b6df8-da23-441e-add7-f8b7efae73a6.png" alt="image" /></p>
<p>In the chart above, we can see the price recently testing the EMA-50 (<em>successfully</em>) before heading directly up to re-test the overhead horizontal resistance at $1660 or so.</p>
<p>In just under a month, the price of Ethereum has bumped against this overhead horizontal resistance <strong>four times</strong>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225668-36483c24-4de1-4307-bb57-04626a495762.png" alt="image" /></p>
<h3 id="heading-momentum-indicator-overlays-support-an-entry-on-the-daily">Momentum Indicator Overlays Support an Entry on the Daily</h3>
<p>If we look at our various custom-coded momentum indicators (<em>which are overlaid on top of the price chart itself</em>), we can see that they're near unanimous in signaling 'entry'.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225680-cdc766af-cb44-4603-a50f-cb765f8bf195.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225695-c131d33b-01da-4893-8cec-d434dd9bc4f2.png" alt="image" /></p>
<h3 id="heading-librehash-reversion-ribbon-v2">Librehash Reversion Ribbon V2</h3>
<p>What we're going to see below should spark some intrigue for readers.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225725-479f9c5c-184c-4b43-aa95-92ea376f82fb.png" alt="image" /></p>
<p>As one can see above, the Librehash Reversion Ribbon V2:</p>
<ol>
<li><p>Has re-colored all of the candles <strong>red</strong>.</p>
</li>
<li><p>The ribbon is showing a recent convergence of the ribbon (from 'red' [<em>bearish</em>] to what should eventually be 'green' when the ribbon changes colors once it faster moving average crosses back over the slower one [<em>these two averages form the basis of the ribbon itself</em>]). In layman's terms, this exemplifies a major shift in <strong>sentiment</strong> for this asset (Ethereum).</p>
</li>
<li><p>The color of the ribbon itself shifted from <strong>dark red</strong> to a <strong>lighter red</strong>. This shift occurred on February 10th, 2023 (<em>less than 5 days ago before we saw this shift in sentiment reflected in the price</em>).</p>
</li>
<li><p>The ribbon dipped <strong>just below</strong> the histogram, but it appears to be curving back upward, currently in a trajectory to cross back <strong>above</strong> the histogram (<em>zero line</em>).</p>
</li>
</ol>
<p><img src="https://user-images.githubusercontent.com/59129716/219225744-1676b9b8-01ab-46bb-99ed-388e92192892.png" alt="image" /></p>
<h3 id="heading-balance-of-power-rsi">Balance of Power RSI</h3>
<p>This is a custom momentum indicator that we've created to track the <strong>underlying buy/sell pressure for a given asset</strong>.</p>
<p>The biggest benefit conferred by this indicator is its ability to track underlying shifts in buying/selling activity <strong>well before other indicators can</strong> (like the RSI(14)).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225756-dae8f855-3455-42e2-8232-3daf8b8816cc.png" alt="image" /></p>
<p>In the photo above, we can see that the inflection point for this indicator was on February 13th, 2023.</p>
<p>In this case, the indicator was not premature in its signal as it aligned with the pivot in price action that occurred on that same day as well.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225768-323ebfe5-4310-4e7d-8a6c-c775482edb1a.png" alt="image" /></p>
<h3 id="heading-balance-of-power-rsi-on-the-weekly-resolution">Balance of Power RSI on the Weekly Resolution</h3>
<p>While the Balance of Power RSI on the daily resolution isn't too insightful, the <strong>weekly resolution</strong> provides us with a <strong>great look</strong> at an underlying shift from bullish exuberance to gradually increased bearish price action (<em>selling</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225783-a40058df-04cc-4d50-86ad-788def43ebd7.png" alt="image" /></p>
<p>Upon closer look, we can see the shift in the Balance of Power RSI's <strong>trend</strong> (overall direction; think 'line of best fit').</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225801-a78ca48c-7da2-4a55-a29b-20caed5eda93.png" alt="image" /></p>
<p>Closer observation reveals that the 'second high' (localized) is lower than the first one.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225820-00fff03e-c3f9-4dfc-8299-789953b87699.png" alt="image" /></p>
<p>Let's look at the other momentum indicators vs. the Balance of Power RSI over the same timeframe.</p>
<p><strong>Librehash RSI(14)</strong></p>
<p><img src="https://user-images.githubusercontent.com/59129716/219225834-8a62ea32-daf5-4589-b291-7378cd1bd67a.png" alt="image" /></p>
<p><strong>Cryptomedication Volatility RSI</strong></p>
<blockquote>
<p><em>This one tracks momentum</em></p>
</blockquote>
<p><img src="https://user-images.githubusercontent.com/59129716/219225848-f8705a3b-3675-4e0b-89f2-6c051455754d.png" alt="image" /></p>
<h4 id="heading-which-one-do-we-trust">Which One Do We Trust?</h4>
<p>As we can see from the charts above, the Balance of Power RSI <strong>strongly contradicts</strong> the Librehash RSI &amp; Cryptomedication Volatility RSI.</p>
<p>In this case, we're going to place more weight on the Balance of Power RSI than the latter two indicators due to the fact that it's specifically designed to track underlying changes in sentiments <strong>well ahead</strong> of other indicators.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We're going to abstain from entering into a position on Ethereum here.</p>
<p>It is likely that the price will continue to increase in the <strong>short term</strong>, but we can't see enough upside over the medium term to justify entry into a 'long' position at the time of writing.</p>
<p>We're also not going to be crazy enough to advocate for a short since the prevailing market sentiment seems to be overwhelmingly bullish at this point (<em>compared to where it was toward the beginning to mid-Fall 2022</em>).</p>
]]></content:encoded></item><item><title><![CDATA[Avalanche DoS 0-Day Ignored by Project Devs]]></title><description><![CDATA[Late in the evening on February 9th, 2022, I received an alert on Telegram from a 'network security' focused channel that read, "Avalanche Blockchain Vulnerable to 0day DoS".
Considering the fact that Avalanche is currently trading with a total marke...]]></description><link>https://librehash.xyz/avalanche-dos-0-day-ignored-by-project-devs</link><guid isPermaLink="true">https://librehash.xyz/avalanche-dos-0-day-ignored-by-project-devs</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 10 Feb 2023 20:47:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676061846524/4b9f5a5f-b009-459f-8db1-37543ca0e9b8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Late in the evening on February 9th, 2022, I received an alert on Telegram from a 'network security' focused channel that read, "Avalanche Blockchain Vulnerable to 0day DoS".</p>
<p>Considering the fact that Avalanche is currently trading with a total market cap in excess of $5.5 billion at the time of writing, news of this nature immediately struck me as something worthy of investigation.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185362-7c242fd3-e7b0-4e5a-8dc9-4f0e5099503f.png" alt="image" /></p>
<p>After I did a cursory search on Google, Reddit, Telegram, Twitter and other social media to see if any other outlets or entities had mentioned the situation, I was a bit confused to see <strong>there was absolutely no discussion on the matter</strong>.</p>
<p>Thus, I took it upon myself to consult the OG source of this information.</p>
<p>As this report will show, despite the widespread lack of coverage and attention paid to this issue, the individual who originally made these findings stumbled upon a <strong>bonafide denial of service bug capable of knocking the entire 'P chain' offline</strong>.</p>
<h2 id="heading-consulting-the-og-intel-report">Consulting the OG Intel Report</h2>
<blockquote>
<p><em>Before moving forward, all credit for this discovery should be given to the author of the original report, whom we're about to familiarize ourselves with. If there are any bounties, rewards, etc., that are to be paid out in pursuance of this piece, I kindly request that you forward them to the aforementioned research ahead of myself. Thank you.</em></p>
</blockquote>
<p>Following the link from the Telegram channel that initially alerted me about this discovery, I was able to find the original author of this report.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185385-01517487-4b7a-477b-b0e3-10cc62f3fc46.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://twitter.com/123456">https://twitter.com/123456</a>; curiosly, they're followed by Huobi and Brock Pierce, among others - so this clearly isn't a "random" of some sort</p>
</blockquote>
<p>The specific tweet in question that notes the zero day is linked below:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/123456/status/1623855584469561344?s=20&amp;t=uQJLfRNQxqzP50db8maEuQ">https://twitter.com/123456/status/1623855584469561344?s=20&amp;t=uQJLfRNQxqzP50db8maEuQ</a></div>
<p> </p>
<p>As we can see above, the author didn't mince any words in their description of the alleged issues on Avalanche's blockchain. They also included a link to a longer form piece they published that details their findings in greater depth.</p>
<p>We're going to go take a peek <a target="_blank" href="https://g.livejournal.com/15852.html">at that report now</a>.</p>
<h3 id="heading-digging-into-the-vuln-analysis-report">Digging into the Vuln Analysis Report</h3>
<p>This report is admittedly a much more interesting read than most proof of concepts you'll ever find.</p>
<p>The report starts with the following:</p>
<blockquote>
<p>"<em>Avalanche just fucked me out of a sizable bug bounty — so I immediately found another bug to disclose to the public. This is a remote API DoS/crash that should OOM chain P and render a vulnerable node mostly or entirely useless.</em>"</p>
</blockquote>
<p><img src="https://user-images.githubusercontent.com/59129716/218185406-16602448-e2f7-493c-8a13-4f1a17cdfd38.png" alt="image" /></p>
<p>Sticking to the facts here, the claims made with respect to the identified vulnerability were:</p>
<ul>
<li><p>The issue renders Avalanche's API endpoint susceptible to being taken down/offline via exploiting the vulnerability to exhaust that resource via denial of service.</p>
</li>
<li><p>Exhausting said resource via denial of service via exploiting this discovered vulnerability could "OOM chain P".</p>
</li>
</ul>
<h3 id="heading-oom-chain-p">"OOM Chain P"?</h3>
<p>to understand this, we're going to need to (lightly) cover how Avalanche works for a second.</p>
<p>The primary difference between Avalanche's design as a 'blockchain' versus other in this space that we've grown familiar with over time is that Avalanche has <strong>three</strong> different chains that users in their ecosystem can interact with.</p>
<p><a target="_blank" href="https://docs.avax.network/overview/getting-started/avalanche-platform">From Avalanche's documentation</a>: "<em>Avalanche features 3 built-in blockchains: Exchange Chain (X-Chain), Platform Chain (P-Chain), and Contract Chain (C-Chain). All 3 blockchains are validated and secured by all Avalanche validators which is also referred as the Primary Network. The Primary Network is a special Subnet, and all members of all custom Subnets must also be a member of the Primary Network by staking at least 2,000 AVAX.</em>"</p>
<p>That description was also supplemented with an accompanying graphic (re-published below for convenience):</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185430-2837b6a1-d063-487d-8dbf-a57f85e5492f.png" alt="image" /></p>
<p>The following screenshot from Avalanche's docs provide a bit more insight into what it is that each individual chain's role is in the ecosystem.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185454-990e6191-b697-46d6-a37f-076605f78a78.png" alt="image" /></p>
<h4 id="heading-quick-takeaways-on-avalanche-chain-structure-context">Quick Takeaways on Avalanche Chain Structure (Context)</h4>
<p>This isn't a tangent here. The purpose of taking the time out to understand the purpose and role of the 'P Chain' within the context of this ecosystem as this will help inform our perspectives later when we assess the magnitude of the issue.</p>
<p>Based on the brief overview from above, we now know that:</p>
<ol>
<li><p>All 3 chains that run on Avalanche rely on the 'P Chain'. Remember, the documentation we just read stated, "<strong>All 3 blockchains are validated and secured by all Avalanche validators which is also referred as the Primary Network</strong>" (Primary Network = 'P Chain')</p>
</li>
<li><p>The existence of each 'subnet' on the protocol depends on the perpetual functionality of the "P Chain"</p>
</li>
<li><p>The consensus mechanism for Avalanche is handled and executed exclusively by the P Chain.</p>
</li>
</ol>
<p>With all the following in consideration, its clear that any takedown of the 'P Chain' would effectively render the entire blockchain itself inoperable.</p>
<p><strong>"What Does 'OOM' Mean?</strong></p>
<p>OOM = Out of Memory</p>
<p>In the next part of this case study, we will soon see how relevant this is to the overall attack vector.</p>
<h3 id="heading-analyzing-the-actual-attack">Analyzing the Actual Attack</h3>
<p>In the blog post, the author put up a link to a YouTube video showing the specific issue at hand.</p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=Pg9w_g4Cv9A">https://www.youtube.com/watch?v=Pg9w_g4Cv9A</a></p>
<p>What the video is showing is:</p>
<ol>
<li><p>Using a software tool called 'Burp Suite' to craft a very specific API request directed at an endpoint.</p>
</li>
<li><p>The API command is a simple `POST' request, which asks for the endpoint to return back a list of validators.</p>
</li>
<li><p>The endpoint does so, but the response appears to be massive.</p>
</li>
</ol>
<p>The issue is inherent in the video alone (<em>if you don't get it, we'll break down why further along</em>). Also, based on what we can see in the video, the alleged mitigations that were suggested by Avalanche to the author of this research will not <strong>have any impact on mitigating this issue</strong>.</p>
<p>Below is a semantic explanation from the author of what occurred in the video we just watched above:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185483-0f6dae53-1c7c-4871-8f67-fb2c913c7be3.png" alt="image" /></p>
<p>The author is right in their assessment of the situation.</p>
<p>We'll find out that there are a few other issues with this current situation as it is on Avalanche and why some of the mitigations that they've already put in place could be bypassed with relative ease.</p>
<h2 id="heading-running-our-own-tests-on-the-avalanche-main-api-endpoint">Running Our Own Tests on the Avalanche Main API Endpoint</h2>
<blockquote>
<p><em>No malicious or nefarious conduct was taken by the author of this study. This exercise did not result in actually disabling the Avalanche API endpoint</em> (as that would just be an outright attack on the network at that point). <em>This testing also did not require crafting any purposefully malicious inputs or behaving in a way outside of what has been explicitly specified in Avalanche's documentation</em></p>
</blockquote>
<p>With that disclaimer out of the way, let's get started.</p>
<p>While the research proffered by the OG intelligence report appeared more than credible, it's good practice to roll your sleeves up and get your 'hands dirty' as well if you have the chance.</p>
<p>Doing so allows you to independently verify that what's been alleged is actually the case and may also enable you to discover a few supplementary facts or developed perspectives not present in the initial report.</p>
<h3 id="heading-avalanche-api-documentation">Avalanche API Documentation</h3>
<p>From here, our first trip is to <a target="_blank" href="https://docs.avax.network/apis/avalanchego/public-api-server">Avalanche's API documentation</a>.</p>
<p>The documentation starts off by letting us know that, "<em>There is a public API server that allows developers to access the Avalanche network without having to run a node themselves. The public API server is actually several AvalancheGo nodes behind a load balancer to ensure high availability and high request throughput.</em>"</p>
<p>As they note, their public API server is hosted at <a target="_blank" href="http://api.avax.network"><code>api.avax.network</code></a> for the Avalanche mainnet. In order to make calls on the endpoint that draws data from one of the 3 chains, one has to append the appropriate subdirectory location for that respective chain to the API URL endpoint.</p>
<p>Thus, there are one of three potential Avalanche API endpoint URLs you will call (<em>contingent on which chain you want to interact with</em>), and they are:</p>
<ol>
<li><p><strong>C-Chain</strong> = <a target="_blank" href="https://api.avax.network/ext/bc/C/rpc"><code>https://api.avax.network/ext/bc/C/rpc</code></a></p>
</li>
<li><p><strong>X-Chain</strong> = <a target="_blank" href="https://api.avax.network/ext/bc/X"><code>https://api.avax.network/ext/bc/X</code></a></p>
</li>
<li><p><strong>P-Chain</strong> = <a target="_blank" href="https://api.avax.network/ext/bc/P"><code>https://api.avax.network/ext/bc/P</code></a></p>
</li>
</ol>
<p>Obviously, we're most interested in the third option.</p>
<h3 id="heading-finding-the-api-documentation-containing-methods-for-calling-the-p-chain">Finding the API Documentation Containing Methods for Calling the 'P Chain'</h3>
<p>Fortunately, this is all on the same site hosting this documentation <a target="_blank" href="https://docs.avax.network/apis/avalanchego/apis/p-chain">right here</a>. More specifically, the API call that we're interested in looking a bit closer at is the <code>platform.getCurrentValidators</code> <a target="_blank" href="https://docs.avax.network/apis/avalanchego/apis/p-chain#platformgetcurrentvalidators">method</a>.</p>
<p>This method is defined as being used to "<em>list the current validators of the given subnet</em>'. However, what we'll see is that this API request actually works <strong>much differently in practice</strong> (<em>which is a flaw in the design and logical, sane API design by Avalanche</em>).</p>
<p>Below is the 'signature' (<em>basically a list of all the different parameters &amp; subparams that can be extracted using this call on the endpoint</em>):</p>
<pre><code class="lang-json">platform.getCurrentValidators({
    subnetID: string, <span class="hljs-comment">// optional</span>
    nodeIDs: string[], <span class="hljs-comment">// optional</span>
}) -&gt; {
    validators: []{
        txID: string,
        startTime: string,
        endTime: string,
        stakeAmount: string,
        nodeID: string,
        weight: string,
        validationRewardOwner: {
            locktime: string,
            threshold: string,
            addresses: string[]
        },
        delegationRewardOwner: {
            locktime: string,
            threshold: string,
            addresses: string[]
        },
        potentialReward: string,
        delegationFee: string,
        uptime: string,
        connected: bool,
        signer: {
            publicKey: string,
            proofOfPosession: string
        },
        delegators: []{
            txID: string,
            startTime: string,
            endTime: string,
            stakeAmount: string,
            nodeID: string,
            rewardOwner: {
                locktime: string,
                threshold: string,
                addresses: string[]
            },
            potentialReward: string,
        }
    }
}
</code></pre>
<p>As noted above, this method is defined as being purposed for returning back the "<em>current validators of the given Subnet</em>".</p>
<p>But if we look at how the various parameters are defined and their usage within the context of this API call, the cause of the issue becomes readily apparent.</p>
<p>Specifically, one would imagine that the <code>subnetID</code>param would be required for this call to evaluate successfully on the endpoint - but it is not. The docs define <code>subnetID</code> as a "<em>the subnet whose current validators are returned</em>". But goes on to state that "<em>if omitted</em>, <strong>returns the current validators of the Primary Network</strong>" (P Chain)</p>
<p>Similarly, the `nodeIDs' param is defined as a "<em>list of the NodeIDs of the current validators to request</em>", but "<em>if ommitted</em>, <strong>all current validators are returned</strong>".</p>
<p>Below is an excerpt from the 'signature' for this API method that defines all of the information that accompanies <strong>each validator</strong>.</p>
<pre><code class="lang-json">validators: []{
    txID: string,
    startTime: string,
    endTime: string,
    stakeAmount: string,
    nodeID: string,
    weight: string,
    validationRewardOwner: {
        locktime: string,
        threshold: string,
        addresses: string[]
    },
    delegationRewardOwner: {
        locktime: string,
        threshold: string,
        addresses: string[]
    },
    potentialReward: string,
    delegationFee: string,
    uptime: string,
    connected: bool,
    signer: {
        publicKey: string,
        proofOfPosession: string
    },
    delegators: []{
        txID: string,
        startTime: string,
        endTime: string,
        stakeAmount: string,
        nodeID: string,
        rewardOwner: {
                locktime: string,
                threshold: string,
                addresses: string[]
        },
        potentialReward: string,
    }
}
</code></pre>
<h3 id="heading-executing-this-api-call-on-the-avalanche-endpoint">Executing This API Call on the Avalanche Endpoint</h3>
<p>For the sake of exploration, I decided to go ahead and execute this call on the provided Avalanche endpoint.</p>
<p>The sample curl command given by Avalanche for this method was:</p>
<pre><code class="lang-bash">curl -X POST --data <span class="hljs-string">'{
    "jsonrpc": "2.0",
    "method": "platform.getCurrentValidators",
    "params": {},
    "id": 1
}'</span> -H <span class="hljs-string">'content-type:application/json;'</span> 127.0.0.1:9650/ext/bc/P
</code></pre>
<p>We're going to change this command slightly so that:</p>
<ol>
<li><p>The Avalanche endpoint is inserted in the place of the IP address</p>
</li>
<li><p>The curl command is formatted a bit more coherently for the sake of portability and readability.</p>
</li>
</ol>
<p>Without wasting time detailing those efforts, I have that curl command published below.</p>
<pre><code class="lang-bash">curl --location --request POST <span class="hljs-string">'https://api.avax.network/ext/bc/P'</span> \
--header <span class="hljs-string">'Content-Type: application/json'</span> \
--header <span class="hljs-string">'Content-Length: 77'</span> \
--data-raw <span class="hljs-string">'{
  "id":2,
  "method":"platform.getCurrentValidators",
  "jsonrpc":"2.0"
}'</span>
</code></pre>
<p>For starters, I (foolishly) ran this in a naked terminal. Just for kicksj to see what would happen.</p>
<p><img src alt class="image--center mx-auto" /></p>
<p>As we can see from the GIF above, the response that's generated from the endpoint is <strong>absolutely massive</strong>.</p>
<p>Granted, there is a 1015 error that's incurred everytime attempts to run the command subsequently on the same device (likely due to strong rate limiting to try to mitigate the situation), but this is something that can be bypassed with ease as we'll see later.</p>
<h3 id="heading-running-the-command-in-postman">Running the Command in Postman</h3>
<p>After seeing the type of output that was generated by the response when I pinged the endpoint, I decided to try the curl command in Postman to see if I could get a gauge of how <strong>large</strong> the response was.</p>
<p>The result was actually <strong>pretty nuts</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1676061381327/3f167e85-0676-4c77-9334-b5c2a8a639de.gif" alt class="image--center mx-auto" /></p>
<p>For those curious about what the crafted request looks like in Postman, here it is:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185540-10b9d167-c5ab-4922-802c-1b99c77a60ee.png" alt="image" /></p>
<p>Running this command in Postman causes it to crash <strong>every single time its ran</strong> (<em>tried it on different computers, diff operating systems &amp; browsers</em>). But I could see that the value of the response fed back from the server was &gt;20MB+, which is actually preposterous for this type of data (JSON).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185551-3b7c3d07-3292-4d4d-b7df-38095515db36.png" alt="image" /></p>
<p>At 20+ MB, the size of the response is <strong>far in excess</strong> of what anyone would want their API endpoint to be returning for <strong>any request</strong> when the <strong>data is in this format</strong> (<em>also not chunked at all</em>).</p>
<h2 id="heading-avalanches-entire-network-could-be-knocked-off-with-ease">Avalanche's Entire Network Could be Knocked Off With Ease</h2>
<p>None of the supposed mitigations that Avalanche has proposed will assuage this situation in the least bit.</p>
<p>I am aware that there is a section of the API documentation that notes that the API requests made on the main public API endpoint hosted by Avalanche are supposed to be load balanced.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185575-82f91010-0ff7-4d7e-b101-056ef947919b.png" alt="image" /></p>
<p>Going back to the panel on Postman that shows the cookies embedded by the API endpoint reveals what mechanism Avalanche is using for their load balancing.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185587-1f5c51ef-b876-482a-98ff-aa940c2ce108.png" alt="image" /></p>
<h3 id="heading-aws-alb-cookies">AWS ALB Cookies</h3>
<p>These cookies are deployed to create "sticky sessions" for one's load balancer implementation provisioned with AWS.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185611-f9be4d97-8ab0-4041-ba1a-e5dcc2c2eac5.png" alt="image" /></p>
<p>These cookies essentially are attached to various users making requests on a load-balanced endpoint to ensure that the user interacts with the same internal endpoint among the load-balanced services.</p>
<h3 id="heading-how-this-can-be-trivially-bypassed">How This Can Be Trivially Bypassed</h3>
<p>If we were to append 8KB+ of data to the end of our request, then the servers will no longer be able to tag us as an entity, effectively eroding whatever protections were granted by the WAF (web application firewall) &amp; its security assurances on the API endpoint as well.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185629-e4df189e-7ab5-4ef3-93c3-087add360261.png" alt="image" /></p>
<p>[<a target="_blank" href="https://kloudle.com/blog/the-infamous-8kb-aws-waf-request-body-inspection-limitation/">source</a>]</p>
<h3 id="heading-other-factors-making-this-vulnerability-a-done-deal">Other Factors Making This Vulnerability a Done Deal</h3>
<p>Since the size of the request is so nominal on our side (as the sender), it would be virtually impossible for Avalanche to try to scan the traffic headed to its WAF setup in order to parse between "legitimate" and non-legit activity.</p>
<p>This is <strong>especially true</strong> when considering the fact that this payload is generated by virtue of submitting <strong>a legitimate request to the server</strong>. We not only followed the API's documented methods &amp; parameters, <strong>but we also</strong> explored this attack vector by <strong>using the 'example' request provided on their site for this method</strong> (<em>seriously</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/218185643-8cd913f8-d5c4-4e8a-a22c-43e858741baf.png" alt="image" /></p>
<h3 id="heading-hopefully-avalanche-pays-the-diligent-researcher-that-uncovered-these-issues">Hopefully Avalanche Pays the Diligent Researcher That Uncovered These Issues</h3>
<p>He did his job and found a legitimate <strong>denial of service vulnerability</strong>.</p>
<p>It would be trivially easy to exhaust the main public API endpoint for Avalanche with the information we've gathered here today.</p>
<p>If you've read up to this point and you're at somewhat of a loss because you were expecting to see a 'walkthrough' or guide on how to do so - sorry. You won't find one here and that's only due to a personal code of ethics &amp; just general decorum.</p>
<p>For those that are familiar with the topics discussed in this vulnerability report, I'd imagine that the attack vector became glaringly obvious for you the second you saw the YouTube video referenced at the top of this piece.</p>
<p>Hopefully publishing this report prompts the Avalanche team to take the safety and security of their $5.6 billion platform a little more seriously.</p>
]]></content:encoded></item><item><title><![CDATA[Generating Bitcoin Address from One Word]]></title><description><![CDATA[I'm curating this write-up on the fly to demonstrate that I know what I'm talking in relation to my directive to all my subscribers that they should cease using Ledger wallets as soon as possible (as in not one second should be spared in ensuring tha...]]></description><link>https://librehash.xyz/generating-bitcoin-address-from-one-word</link><guid isPermaLink="true">https://librehash.xyz/generating-bitcoin-address-from-one-word</guid><category><![CDATA[Bitcoin]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[crypto]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Mon, 30 Jan 2023 04:55:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1675054436451/b797ad7a-6bf4-4697-b5cb-afe187b11bb7.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I'm curating this write-up on the fly to demonstrate that I know what I'm talking in relation to my directive to all my subscribers that they should <strong>cease using Ledger wallets as soon as possible</strong> (as in not one second should be spared in ensuring that one's funds are extracted from one of these devices if possible).</p>
<h2 id="heading-quick-summary-of-how-this-is-going-to-go-down">Quick Summary of How This is Going to Go Down</h2>
<p>Using nothing more than a couple of rudimentary terminal commands as well as a nifty git repo (html-based page that can be run offline), I'm going to show users how to generate a valid Bitcoin address from scratch using one word (librehash).</p>
<p><strong>Purpose of This Exercise</strong></p>
<p>To make it clear that I have a high level of knowledge, understanding &amp; command of blockchain concepts. This should result in the understanding that users are being warned by a highly credible source.</p>
<h2 id="heading-setting-the-stage">Setting the Stage</h2>
<p>Okay, in order to do this, we need to get organized for a second.</p>
<h3 id="heading-figuring-out-what-type-of-address-we-want-to-create">Figuring Out What Type of Address We Want to Create</h3>
<p>Ever since BIP11/BIP12 - Bitcoin transactions have been oriented in such a way to where the recipient provides the spending conditions for any Bitcoin that they "receive" (by virtue of their formed address).</p>
<p>In laymen's terms - creating a run-of-the-mill Bitcoin address and passing that to someone for payment is also like you telling that individual:</p>
<blockquote>
<p>"<em>Hey, I'd prefer it if you established a condition that says that I must provide some value that, when hashed with sha256 [twice], then hashed with ripemd160, provides the equivalent result. Then, when that's done - I want the protocol to assess my accompanying signature next to that value that I provided (assuming it rendered 'true' for the first half of the script) and determine whether there's a match. If there is - then, and only then, should I be allowed to spend these funds in question)</em></p>
</blockquote>
<p>That's a mouthful - but in everyday language, that just amounts to a generic Bitcoin address.</p>
<p>The blockchain sees it as conditions to spend.</p>
<p>Make sense? Cool.</p>
<h2 id="heading-we-need-to-craft-a-p2sh-transaction">We Need to Craft a P2SH Transaction</h2>
<p>That stands for pay-to-script-hash ; sort of similar to P2PKH, except in this case it allows us to make a payment to a script that could have a wide range of mandated conditions to fulfill before spending (this doesn't have to be related to a private or public key if we don't want it to be).</p>
<p><strong>Quick Background</strong></p>
<p>P2SH was <a target="_blank" href="https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki">instantiated with BIP16</a>. There was a bit of community in-fighting at the time - but fortunately (for us in this scenario), it made it through.</p>
<p>As noted in the text above, this BIP (among some other augmentations) cemented the principle of shifting redemption considerations to the receiver (vs. being imposed by the sender).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387083-b41e587e-22db-4d3e-a73e-c0b23b38ef51.png" alt="image" /></p>
<p>This next bit is extremely important:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387112-ea2213e4-c387-40e7-aefc-3aec8941f052.png" alt="image" /></p>
<p><strong>Unpacking the Above</strong></p>
<blockquote>
<p>"<em>The benefit is allowing a sender to fund any arbitrary transaction, no matter how complicated, using a fixed-length 20-byte hash that is short enough to scan from a QR code or easily copied and pasted.</em>"</p>
</blockquote>
<p><strong>However</strong>, there are certain caveats that must be observed.</p>
<p>Specifically:</p>
<blockquote>
<p>"<em>Transactions that redeem these pay-to-script outpoints are only considered standard if the serialized script - also referred to as the redeemScript - is, itself, one of the other standard transaction types.</em>"</p>
</blockquote>
<p>Our guidance for how we should be manifesting a transaction of this nature can be found in '3' (among the rules for validation of p2sh transactions):</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387138-64914451-15c3-4bc8-8cf0-bf02980e6226.png" alt="image" /></p>
<p>This gives us our next directive for the avenue that we must pursue for my goal of creating a Bitcoin address from the word "librehash"</p>
<h2 id="heading-first-step-generate-the-appropriate-script">First Step: Generate the Appropriate Script</h2>
<p>We'll keep this simple.</p>
<p>The script in question that we're going to use is: <code>op_hash160 [librehash hashed] op_equalverify</code></p>
<h3 id="heading-explaining-the-script-that-we-just-created">Explaining the Script That We Just Created</h3>
<p>For reference, this page on the <a target="_blank" href="https://en.bitcoin.it/wiki/Script">Bitcoin Wiki</a> is still the undisputed <em>best location on planet earth to reference op codes on the Bitcoin protocol</em>.</p>
<h3 id="heading-what-is-ophash160">What is 'OP_HASH160'?</h3>
<p>This one is simple. OP_HASH160 executes two consecutive hash operations; the first is sha256, followed ripemd160 (to concatenate the SHA256 output).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387159-7e00e723-f0e4-47c7-aaf5-5386c47afc13.png" alt="image" /></p>
<p><strong>Why Did We Go With This One?</strong></p>
<p>Because we need to ensure that the final output from all of these operations is truncated down to 20 bits per the specifications outlined in BIP16.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387176-de44dd03-16fb-4ff8-9bc5-931764a9c4c1.png" alt="image" /></p>
<blockquote>
<p>remember?</p>
</blockquote>
<h3 id="heading-what-is-opequal">What is 'OP_EQUAL'?</h3>
<p>This one is super simple (see below):</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387187-1ef55ccb-b3f5-4a3f-9cc9-22828b091dc4.png" alt="image" /></p>
<p>Basically, it means that we take the top two items on the stack &amp; assess whether they are equal to one another</p>
<h3 id="heading-all-of-these-operations-take-place-in-a-stateless-fashion-facilitated-by-script">All of These Operations Take Place in a Stateless Fashion Facilitated By 'Script'</h3>
<p>Look up, 'What is Bitcoin Script language?', and there will be a &gt;90% chance that you'll come across some source on the internet that will describe it as an "archaic", 'forthright' smart contracting language for Bitcoin.</p>
<p>This is...a vague definition.</p>
<h3 id="heading-simple-way-to-think-of-script-on-bitcoin">Simple Way to Think of 'Script' (on Bitcoin)</h3>
<p>It is simply a pre-generated execution sequence that runs from start to completion in one loop (<em>before the program is killed; there is no 'loop' in the 'Script' programming language on Bitcoin, so we have an indisputable sense of a "start" and a "finish"</em>).</p>
<p><strong>For the Visual Learners Out there</strong></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387212-860b61e2-2f67-4bb3-8623-dca0955000c0.png" alt="image" /></p>
<p><strong>Just kidding</strong> (although what's above is entirely accurate).</p>
<p>But here's a more user-friendly gif that shows the simple execution of the 'Script' sequence (this is essentially us looking at the 'cells' through a "microscope" if Bitcoin addresses were people [Biology]):</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387568-8847a00d-e0a9-43f1-b72c-b5b92f15a133.gif" alt="scriptgif" /></p>
<h2 id="heading-necessary-tools-for-executing-this-endeavor">Necessary Tools For Executing This Endeavor</h2>
<p>There are two tools that we're going to use for this.</p>
<p>They are listed below (urls):</p>
<ol>
<li><p><a target="_blank" href="https://improvein.github.io/bitcoin-forge/#/">https://improvein.github.io/bitcoin-forge/#/</a></p>
</li>
<li><p><a target="_blank" href="https://gchq.github.io/CyberChef/">https://gchq.github.io/CyberChef/</a></p>
</li>
</ol>
<p>We're a little out of order, but we're going to start with the second item on the list here (GCHQ Crypto Chef Tool).</p>
<blockquote>
<p><em>the what-a-what?</em></p>
</blockquote>
<p>Before we dig into that, let's just check out the second link in question here. (GCHQ CyberChef)</p>
<p><strong>CyberChef Tool Needed to Hash Out Librehash</strong></p>
<p>This would be much more efficient via bash script through the terminal (published below for all those that want that), but since not everyone reading this is a fan of using terminals, let's stick to GUIs, shall we?</p>
<h3 id="heading-using-gchq-to-chef-up-our-bitcoin-address"><strong>Using GCHQ to 'Chef' Up Our Bitcoin Address</strong></h3>
<p><code>Note: this is an open source app</code> <a target="_blank" href="https://gchq.github.io/CyberChef/"><code>that can be found on GitHub</code></a></p>
<p>Upon visiting the site, users should see something similar to the following:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215387607-6e52cc26-0af6-4d35-bd32-a77f1fe86303.png" alt="image" /></p>
<p>This tool will allow us to transform our quasi-seed phrase into the hashed output that we need for this exercise.</p>
<p><strong>Recalling What We're Looking For Here</strong></p>
<p>The '<code>op_hash160</code>' output of the word 'librehash' (<em>we're going to ignore base58 encoding or hexadecimal/binary format delineations here for the sake of KISS</em>)</p>
<p><strong>What Does Hash_160 Do Again?</strong></p>
<p><strong>op_hash160</strong> = <code>OP_HASH160</code> = <code>ripemd160</code> of <code>SHA256(sha256(x))</code></p>
<p>This may seem a bit tricky, but this should be simple to do. So, without further ado - let's get started.</p>
<p>First, we need to hash the word 'librehash' with sha256, then take that output and hash it against sha256 once again - then, finally, hash the <strong>second output with ripemd160 to truncate the 32-bit sha256 hash to 20 bytes</strong></p>
<p>Rather than outlining all of this verbosely, I decided to get creative and make a video (also don't want to be too redundant here).</p>
<p>View below:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388512-8ca338e0-49ca-4831-a1e1-2c302a08153c.gif" alt="bitcoinhash" /></p>
<h2 id="heading-more-of-a-command-line-junkie">More of a Command Line Junkie?</h2>
<p>Understandable.</p>
<p>The script below should render the same result when executed (bash).</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/sh </span>

<span class="hljs-comment">#Lets generate a directive on the terminal for the user running the script</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">'Pick a password to hash into your p2sh wallet'</span>

<span class="hljs-comment">#Before we do that we want to make sure that the tty output is silenced so that we dont leave ourselves vulnerable to being compromised by potential bad actors that have managed to get a hold of our bash history somehow</span>
stty -<span class="hljs-built_in">echo</span>

<span class="hljs-comment">#this next command takes the outputted response from the stdin and assigns it to the word pass which is important</span>
<span class="hljs-built_in">read</span> pass 

<span class="hljs-comment">#this next command will pipe the password that we made earlier into openssl which will hash that with sha256</span>
<span class="hljs-built_in">echo</span> <span class="hljs-variable">$pass</span> | openssl dgst -sha256 &gt;&gt; /tmp/firstrun.txt

<span class="hljs-comment">#we need to rinse repeat again though so lets get to it</span>
cat <span class="hljs-string">"/tmp/firstrun.txt"</span> | openssl dgst -sha256 &gt;&gt; /tmp/secondrun.txt

<span class="hljs-comment">#great we are almost done we just need to pipe this one more time through openssl but this time for the sake of generating a 20 byte output we will ultimately throw into our script</span>
cat <span class="hljs-string">"/tmp/secondrun.txt"</span> | openssl dgst -ripemd160 | xclip -sel clip -rmlastnl

<span class="hljs-comment">#for the xclip command users will need to install that via their apt repo if you are using ubuntu or debian cant speak to other distros just check </span>
<span class="hljs-comment">#that command is useful because it pipes the output straight to our clipboard</span>
<span class="hljs-comment">#now its time to clean up </span>

bleach=<span class="hljs-string">'bleachbit -s "/tmp/firstrun.txt" &gt; "/dev/null" 2&gt;&amp;1'</span>

<span class="hljs-comment">#the command above uses the bleachbit tool to scrub the first outputted file from our tmpfs even though it should be wiped after we end our session anyway since tmpfs is RAM </span>
<span class="hljs-comment">#the above command only gave a directive to execute when the newly created bleach variable is called in our subshell so lets try it out </span>
<span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-variable">$bleach</span>"</span>

<span class="hljs-comment">#we could be super careful and create a conditional script that only proceeds if the tmp directory is devoid of the file in question that we just attempted to bleach out of existence with the above command but I dont think that we need to go that overkill with this</span>
bleachblonde=<span class="hljs-string">'bleachbit -s "/tmp/secondrun.txt" &gt; "/dev/null" 2&gt;&amp;1'</span>

<span class="hljs-comment">#this is a bit redundant but I ran the commands separately for the sake of being demonstrative here</span>
<span class="hljs-built_in">eval</span> <span class="hljs-string">"<span class="hljs-variable">$bleachblonde</span>"</span>

<span class="hljs-comment">#we need to turn the terminal on</span>
stty <span class="hljs-built_in">echo</span> 

<span class="hljs-comment"># now we are done</span>

<span class="hljs-built_in">exit</span>
</code></pre>
<p><strong>Super Important Note Here</strong></p>
<p>When running this script, I noticed that I was getting a different output than the GCHQ tool.</p>
<p>This confused the living hell out of me (because this <strong>should not happen under any circumstance since all hash signatures being used here are deterministic</strong>)</p>
<p><em>The Culprit</em> = prefixed '(stdin)' tag that openssl outputs:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388616-4ad34a60-4bc2-4b56-8325-3c039e3df2f0.png" alt="image" /></p>
<p>The best immediate solution though would be to merely output the last 64 characters (32 bytes) of the file where we piped the hashed result into. Problem solved.</p>
<p><strong>Shouldn't Screw Anyone Though</strong></p>
<p>If one were to consistently use that bash script (and only that), then the output would deterministically be the same (we're dipping into stateless address generation / BIP38 territory here); but its best to do things in the most consistent, interoperable way possible (as recommended by the IETF in numerous RFCs).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388645-f886d9cb-ed0b-44f6-9e60-03739284f372.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://tools.ietf.org/html/rfc1310">time traveling capsule</a></p>
</blockquote>
<p>With all of that being said...We did it!</p>
<p>No time to pat ourselves on the back though - there's still more work that must be done.</p>
<h2 id="heading-generating-our-transaction-conditions">Generating Our Transaction Conditions</h2>
<p>For clarity's sake, the rendered output that we're going to go with is the one that was produced by the GCHQ tool (since this is the easiest to replicate for everyone following alone).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388676-d0cfe80c-2af2-4da8-beca-ea776605112d.png" alt="image" /></p>
<p><em>For the record the output (20-byte) should be:</em> <code>195fe1018a63dd4649af19afdbca7edc01fb3c93</code></p>
<h2 id="heading-visiting-the-bitcoin-forge-toolkit">Visiting the 'Bitcoin Forge' Toolkit</h2>
<p>I'm not entirely sure who the fellas are behind this tool (the first link that I published above), but it is <strong>absolutely magnificent</strong>.</p>
<p>Users can essentially craft any transaction of their choosing with a high level of granularity in their preference decision <em>(down to the deliberate crafting of a wallet address via preferred transaction type if that's meaningful)</em></p>
<blockquote>
<p><em>"Okay, what's the website dude?"</em></p>
</blockquote>
<p>URL = <a target="_blank" href="https://improvein.github.io/bitcoin-forge/#/">https://improvein.github.io/bitcoin-forge/#/</a></p>
<p>This site is 1 million percent safe and so is the code ; you can audit it for yourselves here: <a target="_blank" href="https://github.com/improvein/bitcoin-forge">https://github.com/improvein/bitcoin-forge</a></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388710-9a22222c-678d-4566-b68d-f92abb28814d.png" alt="image" /></p>
<blockquote>
<p><em>my gripe here though is that the calls are made internally into the file system &amp; also there are no integrity hashes accompanying the loaded .js, which we definitely want to include for an app of such a sensitive nature like this one; these are ultimately trivial additions to add in, in the grand scheme though</em> (yeah, I forked the codebase, hacked around and attached argon2-driven stateless bitcoin address generation leveraging the same 'memwallet' specs '<a target="_blank" href="http://Keybase.io">Keybase.io</a>' did in their Bitcoin live example)</p>
</blockquote>
<p>Enough of me rambling though - let's get to it.</p>
<h2 id="heading-generating-our-conditions">Generating Our Conditions</h2>
<p>Once you get to that site (or spin it up yourself locally), you're going to want to click here:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388733-3b116d05-8d8f-466b-8e3d-806e7ae56c6e.png" alt="image" /></p>
<p>That will take us here:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388741-874a9d1c-1c3c-47d4-be0a-bdc58a1cc01f.png" alt="image" /></p>
<p>No need for intimidation, this is the easy part.</p>
<p>One only needs to follow through as such:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388796-2b166921-746a-4cbf-a342-912e571eaaa8.png" alt="image" /></p>
<blockquote>
<p>if you're curious how this was done manually, there will be another video showing the entire process from this point</p>
</blockquote>
<h3 id="heading-now-we-serialize-the-script">Now We Serialize the Script</h3>
<p>By clicking the 'compile' button:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388808-6ba2e98b-10e6-43b9-ac6f-648fa02b147d.png" alt="image" /></p>
<p>This leaves us with:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388822-e3a56378-bf3a-4c12-9105-0e483e098a3f.png" alt="image" /></p>
<blockquote>
<p>a914195fe1018a63dd4649af19afdbca7edc01fb3c9387</p>
</blockquote>
<h2 id="heading-doubling-back-to-amend-one-minor-detail">Doubling Back to Amend One Minor Detail</h2>
<p>I got ahead of myself here because what we've provided above would serve as the second part of the 'Script' scheme (partitioned by the CODESEPARATOR op_code).</p>
<p>What I just wrote in the paragraph above probably makes zero sense and I'll accept that for now because it's outside of the scope of this write-up.</p>
<p><strong>More to the Point</strong></p>
<p>Given the nature of hashing and cryptography in general, we can "shortcut" some of the address generation process - which will allow us to 'game' the 'Script' into thinking that the script hash is a legitimate hash of something that derived from ecdsa (secp256k1 ; elliptic curve transformed).</p>
<blockquote>
<p>'How does one do this?'</p>
</blockquote>
<p>By running an elliptic curve operation on <strong>any 32-bit</strong> (or '33-bit') input, compressing the result (32 bits) before appending the mainnet version bytes to the result.</p>
<p>or</p>
<p>Simply concatenating ('XOR', perhaps?) two 32-bit strengths, yielding a 64-bit output, then appending '04' (version bytes/flag; can't remember which) to the beginning</p>
<blockquote>
<p><em>quick reminder, make sure that the output is in hexadecimal format</em></p>
</blockquote>
<p>After curating the bash script (and including videos, media, etc.), I realized my folly in adding an erroneous additional sha256 hash operation (there's only one, which must be either derived from a versioned Bitcoin).</p>
<p>So let's step back a minute and see if we can't get ourselves a P2SH address from our original input ('librehash') using a more creative means of deriving said address.</p>
<p>See below:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388842-c32b3a07-585e-4bc3-9964-6a72944e189e.png" alt="image" /></p>
<p>In the photo above, I hashed 'librehash' with 'SHAKE256' (part of the SHA-3 family).</p>
<p>SHAKE is an XOF hash function (variable output hash). This means that it can take a hash of virtually any given length &amp; churn out a uniform output.</p>
<p>Ironically, this is a pain point for SHA-2 (i.e., it doesn't 'pad' inputs well). I imagine that Satoshi knew this, which would explain the insistence on 32-bit architecture &amp; 32-bit / 33-bit inputs (along w base58 encoding) to mitigate padding attacks on transactions that would allow one to actually <strong>forge</strong> the sender's signature (Satoshi knew his shit).</p>
<p>Enough rambling - let's append a mainnet version code to our 64-digit output ('04').</p>
<p>From:</p>
<p><code>c7cc45701351a2f28d2a6677a373672a927b95bce90167dcbb7c48645da51e9a4c5103b41b20b416e62f1ed70e67882d950eab638f2b3e49b660dae2b4cb15bb</code></p>
<p>to:</p>
<p><code>04c7cc45701351a2f28d2a6677a373672a927b95bce90167dcbb7c48645da51e9a4c5103b41b20b416e62f1ed70e67882d950eab638f2b3e49b660dae2b4cb15bb</code></p>
<p>The above would be considered an 'uncompressed' Bitcoin address.</p>
<p>Or, we could try our luck by piping the unaugmented SHAKE256 output of 'librehash' into 'shake128' to render a 32-bit hashed output.</p>
<p>We can append '02' (signaling a valid compressed ecdsa public key in hexadecimal format on the Bitcoin protocol).</p>
<p><code>d665a268d2ab299089a484a65ba55544a51de1527581f8bb76bcfc924bd8f163</code></p>
<p>to:</p>
<p><code>02d665a268d2ab299089a484a65ba55544a51de1527581f8bb76bcfc924bd8f163</code></p>
<p>Then run that output through op_256 (hash256 twice) ; yes , tedious but takes no time in terms of computing cycles.</p>
<p>But we don't even need to do that because we can simply hash our foe-compressed key with ripemd160 and generate a valid address from there.</p>
<p>(remember, p2sh mandates a 20-bit input)</p>
<p><code>02d665a268d2ab299089a484a65ba55544a51de1527581f8bb76bcfc924bd8f163</code></p>
<p>(<em>One</em> <em>ripemd160 operation later</em>)</p>
<p><strong>Renders the following output</strong>: <code>abbdc37f19826d00cd94a7a4707be1cb4956e08c</code></p>
<p>Which we then pipe into a slightly different Bitcoin script:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388880-8a5c7d61-8978-4794-a45a-e51ea09d4516.png" alt="image" /></p>
<p>The 'compile' button serializes it for us: <code>a614abbdc37f19826d00cd94a7a4707be1cb4956e08c87</code></p>
<p>There are plenty of tools in the world that will allow us to transform our valid redemption script into an actual Bitcoin address (like the one I showed you).</p>
<p>And voila:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215388887-a3cecf0a-c97a-4f45-80f9-3cc92563d9d7.png" alt="image" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<ol>
<li><p>Every single operation users were shown in this write-up was performed <strong>offline</strong></p>
</li>
<li><p>This entire write-up sets up a meaningful convo that I would like to have about why wallet providers insist on forcing users to generate addresses via mnemonics (which is literally a human-readable, easy-to-remember <strong>private key, that</strong> users don't even need to interact with)</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[White House Should Be Blaming CFTC for Crypto Market Woes]]></title><description><![CDATA[Earlier today, on January 27th, 2022, the Biden administration published a press release on the White House site titled, "The Administration's Roadmap to Mitigate Cryptocurrencies' Risk", which can be found here.

This press release is weird. Let's w...]]></description><link>https://librehash.xyz/white-house-should-be-blaming-cftc-for-crypto-market-woes</link><guid isPermaLink="true">https://librehash.xyz/white-house-should-be-blaming-cftc-for-crypto-market-woes</guid><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Bitcoin]]></category><category><![CDATA[crypto]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 27 Jan 2023 20:29:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674851120791/71ed3ace-7471-4fad-a1d5-99388ee061b3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Earlier today, on January 27th, 2022, the Biden administration published a press release on the White House site titled, "The Administration's Roadmap to Mitigate Cryptocurrencies' Risk", which can be found <a target="_blank" href="https://www.whitehouse.gov/nec/briefing-room/2023/01/27/the-administrations-roadmap-to-mitigate-cryptocurrencies-risks/">here</a>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215168442-946ca8a1-c3be-4577-9a37-6fea929c10c3.png" alt="image" /></p>
<p>This press release is <strong>weird</strong>. Let's walk down the curious strategy the White House pursued in this publication.</p>
<ol>
<li><p>They begin by lamenting the fact that "<em>2022 was a tough year for cryptocurrencies</em>". That's a bit of an understatement, but sure.</p>
</li>
<li><p>From there, they only touch on <strong>one</strong> critical event by noting the implosion of a "so-called 'stablecoin'", which triggered a cascade of insolvencies in the crypto space.</p>
</li>
<li><p>That statement is followed up with the acknowledgment that "<em>many everyday investors who trusted cryptocurrency companies</em> - <strong>including young people and people of color</strong> - <em>suffered serious losses</em>...", which is where it gets awkward because it's likely that those two demographics were the ones that were impacted <strong>the least</strong> by the chaos. That aside, in this very specific instance, it seems strange to pick out two different demographics of peoples impacted by the fallout in the crypto markets as if their losses are somehow less acceptable than that of anyone else's (<strong>side note</strong>: <em>The author of this piece is young and Black</em>).</p>
</li>
<li><p>From there...the press release inserts an invisible middle finger to both the crypto industry and all those aforementioned folks who were impacted by the chaos of the crypto markets when it enigmatically pivots mid-sentence to say "<em>but</em>, <strong><em>thankfully, turmoil in the cryptocurrency markets has had little negative impact on the broader financial system to date</em></strong>". The statement makes it implicitly clear that despite acknowledging the life-altering losses countless American citizens suffered at the hands of the crypto sphere, it's really 'all good' at the end of the day because, after all, the good ol' USA financial system wasn't impacted by it. So, it really ain't that bad for real. You feel me? (<em>in essence</em>)</p>
</li>
</ol>
<h3 id="heading-the-press-release-gets-worse-from-there">The Press Release Gets Worse From There</h3>
<p>Despite acknowledging just how poorly things went in the crypto sphere last year, the press release failed to concretely pinpoint exactly what led to the fallout.</p>
<p>The press release goes on to state, "<em>While cryptocurrency may be relatively new, the behavior we have seen some cryptocurrency companies exhibit and the risks posed by this behavior are not</em>."</p>
<p>No additional hints are given as to what behavior in specific the White House is referencing but based on their promise in the following sentence to, "<em>ensure that cryptocurrencies cannot undermine financial stability, to protect investors, and to hold bad actors accountable</em>", it appears that they are referring to a crackdown on the improprieties by cryptocurrency companies.</p>
<h3 id="heading-expansion-of-power-is-unnecessary">Expansion of Power is Unnecessary</h3>
<p>The press release explicitly calls out Congress, stating, "<em>congress, too, needs to step up its efforts</em>", then provides an example of what could only assume would qualify as 'stepping up its efforts' when citing a potential expansion of "<em>regulators' powers to prevent misuses of customers' assets - which hurt investors and distort prices - and to mitigate conflicts of interest</em>".</p>
<p>The fact is that these agencies have long since been imbued with the authority to impact regulation in this space in a meaningful fashion. In specific, the CFTC had the power to crack down on FTX's absurd proposal to serve as their own clearinghouse despite having nowhere near the expertise, capital or resources required to do so.</p>
<p>FTX was <a target="_blank" href="https://ledgerx.com/clearing#%3A~%3Atext%3DFTX%20US%20Derivatives%20maintains%20a%2Cwhich%20include%20options%20on%20commodities">licensed and registered with the CFTC</a> as a 'derivatives clearing organization' (DCO). As such, it was their responsibility to monitor and police the activities of the cryptocurrency exchange in the weeks and months leading up to its eventual collapse.</p>
<p>Since then, numerous observers have taken the time to zero in on the questionable behavior of the CFTC over the past few months. Notably, FTX had spent considerable time and resources in pushing forward an agenda to <strong>expand the regulatory powers of the CFTC over the crypto sphere</strong> (<em>which is an initiative that's actually in accordance with what the Biden administration requested in their press release</em>).</p>
<h2 id="heading-probing-into-the-relationship-between-ftx-and-the-cftc">Probing into the Relationship Between FTX and the CFTC</h2>
<p>At the end of November, the Washington Post published a critical, yet necessary piece that peered into the relationship between Samuel Bankman-Fried and Rostin Behnam, head of the CFTC.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215174946-b510c45c-eb6a-4ac8-81f9-0d64534e84cd.png" alt="image" /></p>
<p>The article notes that, "Since <em>last year [2021], the two have worked in parallel on critical initiatives which, if not for the sudden demise of Bankman-Fried's FTX empire, might have radically altered the nation's attempts to govern the freewheeling market for digital currencies.</em>"</p>
<p>How, you ask? Through a bill, largely backed by Samuel Bankman-Fried and FTX, that sought to make the CFTC the de facto agency for all supervisory-related responsibilities for the cryptocurrency space.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215176158-c13477ee-8931-43ad-8ee5-744548d60aef.png" alt="image" /></p>
<p>As shown in the excerpt above from the WaPo piece, there are a number of eyebrow-raising facts surrounding the collaborated efforts of Samuel Bankman-Fried and the CFTC that suggest that further scrutiny is warranted by those in power whose job responsibilities include launching inquiries to investigate potential conflicts of interest or abdications of responsibility by government agencies (<em>particularly regulating bodies like the CFTC</em>).</p>
<p>That idea aside, perhaps what's even more troubling is the fact that the CFTC refused to deny FTX's application to expand the derivatives offering on its <a target="_blank" href="http://FTX.US">FTX.US</a> platform with its proposal of an 'automatic liquidation' machination to manage positions heading into default.</p>
<h3 id="heading-relating-this-back-to-the-white-house-press-release">Relating This Back to the White House Press Release</h3>
<p>A few paragraphs in, the press release makes mention of a report it commissioned to address the risks inherent in the cryptocurrency sphere.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215178684-b6eb70d6-c61c-4774-a8ae-d6dd4bedb546.png" alt="image" /></p>
<p>Notably, this report is mentioned within the context of its admonishment of Congress, stating, "<em>[Congress] could limit cryptocurrencies' risks to the financial system by following the steps outlined by the Financial Stability Oversight Council in its recent</em> <a target="_blank" href="https://home.treasury.gov/system/files/261/FSOC-Digital-Assets-Report-2022.pdf"><em>report</em></a><em>.</em>"</p>
<p>Ironically, it is that <strong>very same report</strong> that blasted the <a target="_blank" href="http://FTX.US">FTX.US</a> derivatives expansion plan that the CFTC was apparently in love with.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215179290-48b0a610-18ef-4389-a3d9-13dfcf2d79fb.png" alt="image" /></p>
<p>In that excerpt above, the FSOC report did everything but call out FTX by name.</p>
<ul>
<li><p>"<em>Platforms typically use some level of collateral and then rely on auto-liquidations of that collateral when a position's value falls below some margin maintenance level</em>" (this describes FTX's handling of derivatives precisely)</p>
</li>
<li><p>The mention of 'leveraged tokens' is an ode to FTX as well, since they invented &amp; introduced them to the crypto markets.</p>
</li>
</ul>
<p>Just in case these references aren't convincing enough, it's worth noting that there's an in-text citation hanging at the end of the paragraph appearing before the first one in the screenshot above that references documentation on FTX US' site detailing 'Spot Margin Trading'.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215180088-70c78999-2aa1-4c28-8df4-2f56b73e16d8.png" alt="image" /></p>
<p>Beyond that and other mentions, a considerable portion of the report is dedicated to outlining the risks of crypto derivatives to U.S. consumers.</p>
<p>Among that content, the most relevant was the report's warning about "automated liquidation":</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215180711-dbdb958d-28c2-40d8-8f63-613127819f78.png" alt="image" /></p>
<p>Summarizing the excerpt above:</p>
<ul>
<li><p>The FSOC report explicitly notes that the <strong>'method of liquidating leveraged positions can have substantial implications for whether the unwinding of those positions affects orderly market conditions</strong>'.</p>
</li>
<li><p>The report then very specifically singles out a method called 'automated liquidation', stating that when "<em>combined with high leverage [it] potentially heightens financial stability risks</em>" while also noting that the price behavior most crypto assets typically exhibit (high volatility) lends them to being more predisposed to triggering this liquidation mechanism relative to other traditional asset classes, thus heightening the dangers.</p>
</li>
</ul>
<p>The report doesn't stop there. Following what you just read in the excerpt above, the FSOC report goes on to note that, "<em>Automated liquidations</em> <strong><em>without appropriate regulatory guardrails</em></strong> <em>are likely procyclical, exacerbating balance sheet distress at a time of falling asset values and potentially creating a cascade of automated liquidations</em>. <strong><em>Compared to alternative liquidation mechanisms, automated liquidation may cause lenders to be more likely to liquidate*</em></strong>.*"</p>
<h4 id="heading-circling-back-to-ftxs-proposal-with-the-cftc">Circling Back to FTX's Proposal with the CFTC</h4>
<p>On March 12th, 2022, Samuel Bankman-Fried <a target="_blank" href="https://www.congress.gov/117/chrg/CHRG-117hhrg48754/CHRG-117hhrg48754.pdf">appeared in front of Congress on behalf of FTX</a> to answer questions related to his exchange's "automatic liquidation" proposal that had been sitting with the CFTC since December 2021.</p>
<p>Below are excerpts from the transcript of Samuel Bankman-Fried's testimony during his opening statements to Congress at that hearing.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215184508-9e4379d6-7356-4a3e-9ff1-ebaaa3c2a11e.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215184621-015a1cd8-6e92-4106-8473-311e741168db.png" alt="image" /></p>
<h3 id="heading-cme-president-duffy-destroyed-ftxs-proposal-at-the-hearing">CME President Duffy Destroyed FTX's Proposal at the Hearing</h3>
<p>Notably, this hearing also had some other major players in the derivatives industry there to weigh in on FTX's proposed "auto-liquidation" feature.</p>
<p>One particularly outspoken member of that panel was the Chairman and CEO of the CME Group, Terry Duffy.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215185125-82d350b1-6d9b-4faa-b84a-c65798fabf19.png" alt="image" /></p>
<p>Rather than offer commentary on Duffy's testimony, this piece will defer to his actual statements, shown in the screenshots below.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215185453-a2392adf-59ad-4e05-a7b2-64b5a283d8ae.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215185480-6376b8ca-0a59-4902-a534-08ccd0afb20b.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215185509-a5e0d12d-27b9-4c44-b7b5-32f64f797ab2.png" alt="image" /></p>
<h3 id="heading-duffy-carves-up-ftxs-auto-liquidation-proposal-too"><strong>Duffy Carves Up FTX's Auto-Liquidation Proposal Too</strong></h3>
<p><img src="https://user-images.githubusercontent.com/59129716/215185598-c70cf077-b083-4c2a-a535-be9f8fc0b490.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215185679-5c5e29fd-42f9-41bf-a83a-1427f9b1238f.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215185734-248d9d2e-b6e9-4468-a657-60b4dcf34775.png" alt="image" /></p>
<h3 id="heading-duffy-even-called-out-the-conflicts-of-interest-between-ftx-and-alameda"><strong>Duffy Even Called Out the Conflicts of Interest Between FTX and Alameda</strong></h3>
<p><img src="https://user-images.githubusercontent.com/59129716/215185802-ee86ed8f-b431-4a5e-9ba0-dc689459b7c6.png" alt="image" /></p>
<p>One observation that will be noted here from the excerpt depicted in the above screenshot is the fact that Duffy very specifically called on the CFTC to investigate the conflicts of interest between Samuel Bankman-Fried and Alameda, while also noting the issues inherent in the firm's relationship with FTX that warranted such scrutiny.</p>
<p><strong>Statements of note from the above screenshot:</strong></p>
<ol>
<li><p>"<em>FTX heralds its use of backstop liquidity providers as a prudent liquidity risk management tool that can be utilized where auto-liquidation fails.</em> <strong>FTX does not identify those potential backstop liquidity providers</strong>. <em>We can only speculate on who they are and their relationship to FTX.</em></p>
</li>
<li><p>"<strong>It is worth noting that Alameda Research, which has common ownership with FTX and was originally founded to exploit cross-border crypto arbitrage opportunities, plays a significant role in managing liquidations and providing liquidity in offshore and cash crypto markets. It is important for market stakeholders and the CFTC to investigate these unknowns further in light of the clear conflicts of interest of such a structure.</strong>"</p>
</li>
</ol>
<p><strong>Duffy Outlines All the Risks FTX's Proposal Created for Customers</strong></p>
<p>This part of his testimony is where he really elucidated the dangers customers at FTX were facing:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215186793-6ed47041-8622-4078-be20-9153d1500be4.png" alt="image" /></p>
<p><strong>Duffy's Closing Statements Finishing Off FTX</strong></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215186883-95f6b128-f9c1-42ba-b286-a5b68992920d.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/215186962-e9fe163a-b1ad-4fd4-bfdd-32ba489b5b17.png" alt="image" /></p>
<p>Yeesh.</p>
<h3 id="heading-white-houses-press-release-shows-they-have-no-clue-whats-going-on">White House's Press Release Shows They Have No Clue What's Going On</h3>
<p>When considering all that was written above, it's clear that the solution to the crypto space's woes is not 'expanding regulatory powers', but rather holding them accountable to exercise those powers effectively.</p>
<p>Proposing sweeping changes and enforcement measures as part of knee-jerk reaction to shocking news in the crypto space without truly probing into the <strong>heart</strong> of the issue is an irresponsible move by the White House.</p>
<p>In parting - consider the fact that this piece you just read was written by one random individual in the crypto space. This was not assisted or informed by any team, agency, or group. These findings and conclusions are the result of independent, non-financed efforts.</p>
<p>With that being said, how much easier should it be for the White House to ascertain what's going on in the crypto sphere so that they can react accordingly? Granted, there's certainly a lot more than crypto on the White House's plate, but given the fact its important enough for them to commission multiple reports and press releases addressing the industry in the space of less than a year, one can strongly argue that perhaps the White House needs to start pointing the finger at itself rather than everyone else.</p>
]]></content:encoded></item><item><title><![CDATA[Story Behind SBF's Robinhood Shares]]></title><description><![CDATA[Before digging into SBF's filing in the FTX bankruptcy docket, keep in mind that he is no longer CEO of FTX, Alameda or any of its affiliated or related entities. Additionally, John J. Ray III, has gone to lengths to make it expressly clear that the ...]]></description><link>https://librehash.xyz/story-behind-sbfs-robinhood-shares</link><guid isPermaLink="true">https://librehash.xyz/story-behind-sbfs-robinhood-shares</guid><category><![CDATA[Bitcoin]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[NFT]]></category><category><![CDATA[Investment]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Fri, 27 Jan 2023 20:17:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674850562841/fb52ac90-d766-428b-8eef-839218cc1fcd.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before digging into SBF's filing in the FTX bankruptcy docket, keep in mind that he is <strong>no longer</strong> CEO of FTX, Alameda or any of its affiliated or related entities. Additionally, John J. Ray III, has gone to lengths to make it expressly clear that the relationship between SBF and FTX is effectively non-existent at this point.</p>
<p>Thus, any filings by Samuel Bankman-Fried in the FTX Bankruptcy docket are in furtherance of his interests as an individual private citizen.</p>
<h4 id="heading-taking-a-peek-at-samuel-bankman-frieds-request-to-exempt-the-robinhood-shares-from-falling-under-injunction">Taking a Peek at Samuel Bankman-Fried's Request to Exempt the Robinhood Shares from Falling Under Injunction</h4>
<p><img src="https://user-images.githubusercontent.com/59129716/215006983-e734daf7-265c-490d-b250-e9bdadbd73f1.png" alt="image" /></p>
<ul>
<li><em>Full-text</em> <a target="_blank" href="https://restructuring.ra.kroll.com/FTX/Home-DownloadPDF?id1=MTQzNjUxNQ==&amp;id2=-1"><em>here</em></a></li>
</ul>
<p>The filing asks the court to deny FTX's petition to place the assets among those that are subject to the 'Automatic Stay' that's typically triggered at the commencement of bankruptcy proceedings. Specifically the filing states, "<em>Mr. Bankman-Fried respectfully requests that the Stay Motion be denied because the FTX Debtors are effectively advancing an argument for a preliminary injunction but have failed to carry their heavy burden of establishing that such an extraordinary remedy is warranted.</em>"</p>
<p>The filing goes on to state, "<em>As the United States Department of Justice obtained a warrant to seize the assets at issue and seized such assets, the Stay Motion is moot. Despite that, the FTX Debtors have not withdrawn the Stay Motion. As a result, Mr. Bankman-Fried is compelled to reply...The FTX Debtors seek to disregard the separate existence of a corporation that is not a party to this action and encumber hundreds of millions of dollars worth of assets to which they have no legal claim. The remedy they seek is extraordinary and inappropriate. Accordingly, the Stay Motion should be treated as a request for a preliminary injunction and subjected to a heightened standard of proof.</em>"</p>
<p>In short, the filing notes that FTX in its capacity as an exchange made a filing requesting for these assets (Robinhood shares) to be included among the already existing assets that had been placed under an 'Automatic Stay', as is typical during Chapter 11 bankruptcy proceedings.</p>
<h3 id="heading-brief-explanation-of-the-automatic-stay-process-in-chapter-11-bankruptcy-proceedings">Brief Explanation of the 'Automatic Stay' Process in Chapter 11 Bankruptcy Proceedings</h3>
<p>The purpose of filing for bankruptcy under 'Chapter 11' is to grant the filing entity a chance to "reorganize" and restructure their business in a manner that will allow them to continue operating insolvency.</p>
<p>As such, these proceedings are almost always accompanied by an 'Automatic Stay' of the filing company's assets. A 'stay' is a general legal term that refers to an "injunction" issued by the courts. In layman's terms, it's an order to cease a pending action(s) and a prohibition against commencing said action(s).</p>
<p>In this case, the automatic stay is a "provision in United States bankruptcy law that temporarily prevents creditors, collection agencies, government entities, and others from pursuing debtors for money that they owe." (<a target="_blank" href="https://www.investopedia.com/terms/a/automaticstay.asp">source</a>).</p>
<p><a target="_blank" href="https://uscode.house.gov/view.xhtml?req=granuleid:USC-prelim-title11-section362&amp;num=0&amp;edition=prelim">U.S. law dictates</a> this goes into effect the second a debtor (<em>company filing for bankruptcy</em>) makes the filing.</p>
<p>Again, <a target="_blank" href="https://www.investopedia.com/terms/a/automaticstay.asp">per Investopedia</a>, "<em>Automatic-stay provisions protect the debtor against certain actions from their creditors, including starting or continuing court proceedings against the debtor; moving to foreclose on a debtor’s property; creating, perfecting, or enforcing a lien against a debtor’s property; and attempting to repossess the collateral.</em>"</p>
<p>The purpose of this provision of Chapter 11 bankruptcy filings is to give the debtor time to get their shit together before creditors and others descend upon them like a bunch of ravenous vultures because they will likely engage the debtor in proceedings that will encumber their ability to restructure their finances properly, which is ultimately counter-intuitive to the interests of all creditors, collectively.</p>
<h3 id="heading-relevant-information-about-emergent-fidelity-technology-ltd">Relevant Information about Emergent Fidelity Technology Ltd.</h3>
<p>It's important to remember that FTX is the debtor here - not Samuel Bankman-Fried, even though the latter is the one that's informally considered to be the individual indebted to FTX customers and lenders.</p>
<p>The shares in question that Emergent Fidelity Technology Ltd. acquired from Robinhood were purchased with funds the holding company received from Alameda Research, which is one of the firms involved in the Chapter 11 bankruptcy proceedings. The holding company, 'Emergent Fidelity Technology Ltd.', is 90% owned by Samuel Bankman-Fried with Gary Wang holding the remaining 10%.</p>
<p>Both individuals are the defendants in a <a target="_blank" href="https://www.justice.gov/usao-sdny/pr/united-states-attorney-announces-charges-against-ftx-founder-samuel-bankman-fried">pending federal case</a> with charges that include multiple counts of fraud perpetrated against their customers in their respective roles as executives at FTX.</p>
<p>As noted in the New York Times and other publications, Gary Wang, one of the founders of FTX, <a target="_blank" href="https://www.nytimes.com/2022/12/21/technology/ftx-fraud-guilty-pleas.html">has already pleaded guilty to four different counts related to the aforementioned pending federal case</a>.</p>
<p>Those counts are reflected in the superseding indictment against Samuel Bankman-Fried, which attaches the former CEO of Alameda Research, Caroline Ellison alongside Gary Wang as co-defendants.</p>
<p>The specific counts to which Gary Wang plead guilty are:</p>
<ol>
<li><p>Conspiracy to Commit Wire Fraud on Customers</p>
</li>
<li><p>Wire Fraud on Customers</p>
</li>
<li><p>Conspiracy to Commit Commodities Fraud</p>
</li>
<li><p>Conspiracy to Commit Securities Fraud</p>
</li>
</ol>
<p>The relevant court filing that includes these charges alongside supplementary 'superseding' information <a target="_blank" href="https://storage.courtlistener.com/recap/gov.uscourts.nysd.590940/gov.uscourts.nysd.590940.6.0.pdf">can be found here</a>.</p>
<h3 id="heading-argument-made-by-sbfs-legal-team-for-denying-ftxs-motion">Argument Made by SBF's Legal Team for Denying FTX's Motion</h3>
<p>In their filing to the bankruptcy docket on January 5th, 2023, Samuel Bankman-Fried's lawyers object to FTX's motion titled, '<em>Debtors' Motion to Enforce the Automatic Stay or, in the alternative, Extend the Automatic Stay</em>' on several different grounds, which are summarized below:</p>
<ol>
<li><p>It is argued that any consideration about whether the shares should be considered as part of the automatic stay is pointless because the Department of Justice's seizure of said shares renders the argument moot since the court is now unable to make any ruling that can impact their status at this point.</p>
</li>
<li><p>It is argued that the debtors' claim to these shares is, in actuality, a request for preliminary injunctive relief. The rationale underlying this argument is a bit more nuanced, but in essence SBF's filing asserts that since the shares were technically never the property of either Alameda or FTX, they cannot qualify for injunctive relief under the 'Automatic Stay' provision of Ch. 11 proceedings. It is then asserted that the debtors still believe they must lay claim to these assets on the basis that their acquisition was only made possible via a loan from Alameda Research and that said the loan was only given under fraudulent pretense or suspicious circumstances. SBF argues that such an assumption is not validated by present facts but rather by allegations. Therefore, imposing an injunctive relief upon such assets would not qualify as applicable under the 'Automatic Stay' but rather as a 'preliminary injunction' (keyword: <strong>preliminary</strong>).</p>
</li>
<li><p>The filing claims that "<em>Mr. Bankman-Fried and Zixiao Wang borrowed the funds for Emergent to purchase the Robinhood Shares from Alameda and a set of loans were memorialized in four different promissory notes.</em>" <a target="_blank" href="http://pdf.secdatabase.com/405/0001140361-22-018827.pdf">It is stated that public records of the transaction can be found within this SEC court filing</a>.</p>
</li>
</ol>
<h2 id="heading-og-motion-filed-by-ftx-requesting-injunction-on-robinhood-shares">OG Motion Filed by FTX Requesting Injunction on Robinhood Shares</h2>
<blockquote>
<p><em>This report is not covering the various claims on the shares in chronological order for coherency purposes as it made more sense to examine SBF's objection in specific before visiting the motion filed by Samuel Bankman-Fried</em></p>
</blockquote>
<p>The original motion for which Samuel Bankman-Fried, BlockFi and other competing parties filed responses in objection to was filed by FTX on December 22nd, 2022, and titled, '<em>Debtors' Motion to Enforce the Automatic Stay or, in the Alternative, Extend the Automatic Stay</em>'.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/215007014-02458c98-62ea-43d3-ba66-522d67a4da8f.png" alt="image" /></p>
<blockquote>
<p><em>This filing can be found</em> <a target="_blank" href="https://restructuring.ra.kroll.com/FTX/Home-DownloadPDF?id1=MTM1NjkxMg==&amp;id2=-1">here</a></p>
</blockquote>
<p>The filing begins by noting, "<em>Approximately 56 million shares of Robinhood Markets, Inc.'s Class A common stock are currently frozen in a brokerage account at ED&amp;F Man Capital Markets Inc. in New York City. Alameda held other assets at EDFM for which there is no dispute as to ownership. However, unlike other Debtor assets at EDFM, the Robinhood Shares were nominally held, on the Petition Date, in street name for an affiliated non-debtor company organized in Antigua and Barbuda named Emergent Fidelity Technologies Ltd. Emergent is a special-purpose holding company that appears to have no other business, and is 90% owned by Samuel Bankman-Fried, former CEO of FTX Trading and former ultimate controlling person of FTX Trading and Alameda.</em>"</p>
<p>Their filing goes on to note "<em>three different competing stakeholders of the Debtors" who</em> have submitted filings laying claim to the shares in proceedings involving the Debtor (FTX), which are:</p>
<ol>
<li><p>BlockFi Lending LLC and BlockFi International LLC</p>
</li>
<li><p>Yonathan Ben Shimon</p>
</li>
</ol>
<h4 id="heading-revelations-from-ftx-about-blockfis-involvement">Revelations from FTX about BlockFi's Involvement</h4>
<p>On page 3 of the FTX filing, it is stated that "BlockFi <em>has been a lender to Alameda for at least three years. With news of FTX's imminent collapse making headlines worldwide, just two days before the Debtors</em> (including FTX Trading and Alameda) <em>filed for bankruptcy, BlockFi scrambled to protect itself from impending losses on antecedent loans by threatening to seek remedies against Alameda if Alameda did not pledge additional collateral for those loans.</em>"</p>
<p>"<em>In response to those threats, and despite the perilous financial position of Alameda and the other Debtors, Alameda's then-CEO Caroline Ellison, with knowledge and encouragement from Mr. Bankman-Fried, purportedly agreed to pledge over $1 billion worth of additional Alameda assets to secure Alameda's outstanding loan obligation to BlockFi. The Robinhood Shares were included in these pledged assets by Alameda's then-CEO, despite the fact that the Robinhood Shares were nominally held by Emergent, because Alameda had then, and continues to have, a property interest in the Robinhood Shares.</em>"</p>
<p>This information substantially diverges from what was included in the objection to the Stay made by Samuel Bankman-Fried in several important ways.</p>
<p>Out of all the new information provided, the most important tidbit in this portion of the filing is the revelation that Alameda included these funds as part of a $1 billion dollar collateral package to BlockFi in November 2022 (<em>this date derived from the filing stating that this occurred</em>, "just two days before the Debtors filed for bankruptcy" since this <em>is known to have occurred on November 11th, 2022</em>)</p>
<p>Notably, this claim was not rebutted or even acknowledged in Sam Bankman-Fried's filing objecting to this motion by FTX.</p>
<h3 id="heading-revelations-from-ftx-about-yonatan-ben-shimon">Revelations from FTX about Yonatan Ben Shimon</h3>
<p>'Yonathan Ben Shimon' (his name is spelled, 'Yonatan' online), is the other creditor that the FTX filing states laid claim to the Robinhood shares owned by Emergent Fidelity Technology Ltd.</p>
<p>In regards to this creditor, the filing states, "<em>Meanwhile, in Antigua, a creditor of FTX Trading, Mr. Ben Shimon, has obtained a freezing injunction from an Antiguan court with respect to the assets of Emergent, including the Robinhood Shares, following the appointment of receivers for Emergent and the Shares. The receivers were appointed after the Antiguant court concluded there was sufficient evidence that the Robinhood Shares were purchased with funds from FTX Trading and, therefore, should be available to pay prepetition claims of creditors of FTX Trading, such as Mr. Ben Shimon. The receivers have purported to replace Mr. Bankman-Fried as sole director of Emergent.</em>"</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>The purpose of this post was just to provide greater information about what's going on behind the scenes as it pertains to Samuel Bankman-Fried and the Robinhood Shares.</p>
]]></content:encoded></item><item><title><![CDATA[Covering Silvergate's Woes]]></title><description><![CDATA[If you've been following the news in the crypto space lately, then it may come as a surprise to you that Silvergate is in some deep shit.
'What are You Talking About? There's Been Plenty of Coverage in the Crypto Space about Silvergate Bank'
Yes...te...]]></description><link>https://librehash.xyz/covering-silvergates-woes</link><guid isPermaLink="true">https://librehash.xyz/covering-silvergates-woes</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Tue, 24 Jan 2023 10:02:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1676508630076/fcefd204-bb9c-4778-ad9f-85442058d457.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1674554479842/b23af4ea-b2c9-40ec-af6f-964072c8d39c.gif" alt class="image--center mx-auto" /></p>
<p>If you've been following the news in the crypto space lately, then it <strong>may come as a surprise to you</strong> that Silvergate is in some deep shit.</p>
<p><strong>'What are You Talking About? There's Been Plenty of Coverage in the Crypto Space about Silvergate Bank'</strong></p>
<p>Yes...technically.</p>
<p>But that coverage has not dug into some of the more serious issues Silvergate faces at the time of writing.</p>
<h3 id="heading-ftx-alamedas-relationship-and-banking-activities-at-silvergate-are-relevant-but-ancillary">FTX + Alameda's Relationship and Banking Activities at SIlvergate are Relevant, but Ancillary</h3>
<p>At this point, it's well-known that Sam Bankman-Fried used Silvergate as his bank of choice for Alameda and (<em>we'll assume</em>) FTX as well, although details on the latter's true banking situation will likely remain opaque until the conclusion of SBF's federal trial and other related court proceedings.</p>
<p>Since the core issue at the heart of the FTX + Alameda collapse deals with the alleged inappropriate use of funds by Sam Bankman-Fried and other co-conspirators named and unnamed in their capacity as executives and leaders at FTX and Alameda, respectively, it was fair to assume that Silvergate would eventually come under some scrutiny since they were the primary financial institution used by both entities.</p>
<p>However, <strong>this is not the biggest issue that Silvergate is facing at the time of writing</strong>.</p>
<h3 id="heading-concerns-re-money-laundering-at-silvergate-bank-by-crypto-companies-not-named-ftx-or-alameda">Concerns RE: Money Laundering at Silvergate Bank by Crypto Companies Not Named FTX or Alameda</h3>
<p>Curiously, despite widespread coverage by various publications of the class action lawsuit initiated by investors against Silvergate in mid-December 2022, few (if any), took the time to delve into <strong>why</strong> the class action lawsuit was being initiated.</p>
<p>Fortunately, finding this out requires that we do no more than defer to the press release published on 'prnewswire' by the law firm spearheading the class action.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210870392-2c53001b-c011-4cf0-974e-1524914d4c3b.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.prnewswire.com/news-releases/pomerantz-law-firm-announces-the-filing-of-a-class-action-against-silvergate-capital-corporation-and-certain-officers--si-301702308.html">https://www.prnewswire.com/news-releases/pomerantz-law-firm-announces-the-filing-of-a-class-action-against-silvergate-capital-corporation-and-certain-officers--si-301702308.html</a> (<em>best to get certain things 'straight from the horse's mouth', as they say</em>)</p>
</blockquote>
<p>Critically, that press release noted the following:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210870614-b83b04bd-2de2-487b-914c-8bd912611152.png" alt="image" /></p>
<p>The above excerpt from the press release informs us:</p>
<ol>
<li><p>That the complaint, in specific, that the "<em>defendants made materially false and/or misleading statements, as well as failed to disclose material adverse facts about the Company's business, operations, and prospects</em>".</p>
</li>
<li><p>The press release goes further to identify exactly what these investors feel Silvergate has 'misled' them about and/or failed to disclose that they gauged to be materially significant. Specifically, the issue is taken with the fact that Silvergate failed to disclose that they did not possess "<em>sufficient controls and procedures to detect instances of money laundering</em>." (which is one hell of a claim to make against a legitimate U.S. financial institution).</p>
</li>
<li><p>The investors also claim that they were left in the dark about a money laundering operation taking place on the platform to the tune of <strong>over $425 million</strong> (again, this is a bombshell).</p>
</li>
<li><p>Investors were misled about the potential likelihood of Silvergate facing punitive measures moving forward. In essence, the PR reasons that given what they understand to be true about Silvergate's current and past state of affairs, the likelihood that the financial institution will "<em>receive regulatory scrutiny and face damages, including penalties and reputational harm</em>" is far greater than what Silvergate had projected either explicitly in communications to investors or implicitly through their failure to divulge certain facts that would have allowed the aggrieved investors to better ascertain the financial institution's future outlook.</p>
</li>
</ol>
<p>After <strong>all of those bombshells</strong>, the press release then goes on to provide more detail about the &gt;$400M+ money laundering figure they alluded to before, stating, "<em>On November 15, 2022, Marcus Aurelius Research tweeted that, 'Recently subpoenaed Silvergate bank records reveal $425 million in transfers from $SI crypto bank accounts to South American money launderers. Affidavit from investigation into crypto crime ring linked to smugglers/drug traffickers.</em>'"</p>
<h4 id="heading-all-of-this-information-was-confirmed">All of This Information Was Confirmed</h4>
<p>Unfortunately, no second or third-hand news sources could be consulted in this endeavor to establish a 'ground truth' regarding the salacious claims made in that press release.</p>
<p>Fortunately, this fact did not prevent us from tracking down the <strong>firsthand sources</strong> alluded to in this press release - which ultimately allowed us to <strong>confirm</strong> that the claims made in this press release were entirely founded. In fact, there are some additional circumstantial facts that strongly suggest that some large stakeholders in Silvergate may have been aware of these facts months prior.</p>
<p>The relevant sources, links to the subpoena/affidavit in question, etc., are all contained within a thread that the author of this piece published on Twitter.</p>
<p><a target="_blank" href="https://twitter.com/librehash/status/1603885565858189312?s=20&amp;t=VDR2iBS_cG4ArvOt_CRM7Q">https://twitter.com/librehash/status/1603885565858189312?s=20&amp;t=VDR2iBS_cG4ArvOt_CRM7Q</a></p>
<p>The last tweet in the Twitter thread linked above reveals that the class action we've been discussing thus far was actually just one of two class actions initiated by investors that were pending against Silvergate at the time.</p>
<p><strong>When it Rains it Pours</strong></p>
<p>At the time of writing, there are <em>four different class action suits pending against Silvergate in federal court</em>:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210875474-a3db32fb-7ddd-42cf-b01a-2f9267156400.png" alt="image" /></p>
<p>The screenshot above only accounts for the class actions that have been filed in federal court. Beyond those, there have been a number of announcements made by other law firms representing different groups of Silvergate investors that have publicly stated their intent to file a complaint against the financial institution at some point in the immediate future.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210876462-fd1fae7a-46d6-4dba-843f-b458934b3918.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/210876487-c8888106-ec33-4832-a50b-6297ecd9aae5.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.prnewswire.com/news-releases/si-lawsuit-alert-levi--korsinsky-notifies-silvergate-capital-corporation-investors-of-a-class-action-lawsuit-and-upcoming-deadline-301714039.html">https://www.prnewswire.com/news-releases/si-lawsuit-alert-levi--korsinsky-notifies-silvergate-capital-corporation-investors-of-a-class-action-lawsuit-and-upcoming-deadline-301714039.html</a></p>
</blockquote>
<p><img src="https://user-images.githubusercontent.com/59129716/210876615-1fa0a512-e498-4da9-a9af-2af6fb5d9c63.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://wreg.com/business/press-releases/cision/20221228NY74403/shareholder-alert-the-gross-law-firm-notifies-shareholders-of-silvergate-capital-corporation-of-a-class-action-lawsuit-and-a-lead-plaintiff-deadline-of-february-6-2023-nyse-si/">https://wreg.com/business/press-releases/cision/20221228NY74403/shareholder-alert-the-gross-law-firm-notifies-shareholders-of-silvergate-capital-corporation-of-a-class-action-lawsuit-and-a-lead-plaintiff-deadline-of-february-6-2023-nyse-si/</a></p>
</blockquote>
<p><img src="https://user-images.githubusercontent.com/59129716/210876728-a252323d-2326-4009-9f45-6e5adb9d867e.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.prnewswire.com/news-releases/silvergate-capital-corporation-nyse-si-shareholder-class-action-alert-bernstein-liebhard-llp-reminds-investors-of-the-deadline-to-file-a-lead-plaintiff-motion-in-a-securities-class-action-lawsuit-against-silvergate-capital-cor-301713945.html">https://www.prnewswire.com/news-releases/silvergate-capital-corporation-nyse-si-shareholder-class-action-alert-bernstein-liebhard-llp-reminds-investors-of-the-deadline-to-file-a-lead-plaintiff-motion-in-a-securities-class-action-lawsuit-against-silvergate-capital-cor-301713945.html</a></p>
</blockquote>
<p>Each one of these actions specifically identifies the &gt;$425+ million money laundering figure cited in the subpoena published by 'Marcus Aurelius' on Twitter (<em>you can find a link to the original post as well as the court document in the Twitter thread published above</em>).</p>
<h2 id="heading-more-carnage-for-silvergate-bank">More Carnage for Silvergate Bank</h2>
<p>As if all the above issues weren't enough, market data shows that Silvergate is trading <strong>40% lower today, alone</strong> (January 5th, 2023).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210877416-6ba5f60b-30d7-4803-9934-55e48ae905d0.png" alt="image" /></p>
<p>At the time of writing, shares in Silvergate Capital Corp. have fallen by &gt;90% in less than a year (<em>dating back to early March 2022</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210877609-2f0a47e5-ca26-46eb-85bf-3c46adbc7e8f.png" alt="image" /></p>
<p>Obviously, things have been shitty for Silvergate bank lately. But it is worth looking into what's prompted this recent landslide in share price for the bank.</p>
<h3 id="heading-deposits-at-silvergate-fell-by-dollar81b">Deposits at Silvergate Fell by $8.1B+</h3>
<p>If you've seen recent headlines from publications covering Silvergate Bank's evolving dumpster fire (<em>we're calling it that because that's what its turning to at this point in time</em>), then you've likely learned that mandatory financial disclosures by the financial institution revealed that clients had pulled &gt;$8B+ from the bank over the past 3 months alone.</p>
<p><strong>Is This a Lot? What's the Big Deal?</strong></p>
<p>Without knowing how much Silvergate had deposited at their institution before this $8B+ reduction, we have no way to assess the gravity of this revelation.</p>
<p>Fortunately, Senator Elizabeth Warren painted a concise portrait of Silvergate's state of affairs up to September 30th, 2022, in a public letter she published that was addressed to the financial institution demanding answers to a litany of questions concerning the financial institution's operations, oversight and risk management controls along with a detailed actionable plan for sustainability in the future following the collapse of FTX &amp; Alameda (<em>among other large depositors at the financial institution, such as BlockFi</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210879423-9df843e7-b3c6-40b2-a035-f8acaa5571bc.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.warren.senate.gov/imo/media/doc/2022.12.05%20Letter%20to%20Silvergate%20Bank%20re%20FTX.pdf">https://www.warren.senate.gov/imo/media/doc/2022.12.05%20Letter%20to%20Silvergate%20Bank%20re%20FTX.pdf</a></p>
</blockquote>
<p>Specifically, Senator Warren noted that, "<em>Last month, you issued a statement asserting that, 'as of September 30, 2022, Silvergate's total deposits from all digital asset customer $11.9 billion'</em>".</p>
<p>That quote is accompanied with a footnote reference, which brings us to a press release on Silvergate's site.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210882822-5b5c6378-60fb-40ad-98eb-c97d886fa36e.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://ir.silvergate.com/news/news-details/2022/Silvergate-Provides-Statement-on-FTX-Exposure/default.aspx">https://ir.silvergate.com/news/news-details/2022/Silvergate-Provides-Statement-on-FTX-Exposure/default.aspx</a></p>
</blockquote>
<h4 id="heading-doing-the-math">Doing the Math</h4>
<p>We know there were $11.9 billion in deposits at the bank on September 30th, 2022. Recent financial data published by the financial institution confirmed this total declined by approximately $8.1 billion.</p>
<p>Quick math here (11.9-8.1), tells us that Silvergate's total deposits stand somewhere in the ballpark of $3.8 billion total. The dollar figure given for the decline in value of deposits at the institution represents a <strong>net change</strong>, so this deficit also accounts for any and all deposits (<em>not withdrawals; positive cash flow</em>) that were made to the bank.</p>
<p>Thus, it's reasonable to assume that the bank's total deposits (as far as we know) currently stand at circa $3.8 billion (<em>although likely even lower given the recent collapse in the share price of the financial institution</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210883845-d8bc46e2-be84-48aa-b2f0-7eb82e0286db.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.ft.com/content/69cd8629-278d-4cd5-a3e7-96d2f6c85f34">https://www.ft.com/content/69cd8629-278d-4cd5-a3e7-96d2f6c85f34</a></p>
</blockquote>
<p>Another piece by 'Financial Times' (FT) revealed that to meet withdrawal requests over the past few weeks, Silvergate was forced to liquidate down &gt;$5B+ of their debt securities, resulting in an actualized of over $700M+ from these sales. At this point, Silvergate <strong>no longer holds any equity capital</strong>.</p>
<p>At the end of September 2022, the financial institution's 'book value' stood at $1.3B.</p>
<p><strong>Other Notable Facts</strong></p>
<ol>
<li><p>Silvergate has laid off ~40% of its staff</p>
</li>
<li><p>Beyond the $3.8B+ in deposits the bank holds, Silvergate was also purportedly carrying $4.6B+ in cash and equivalents at the end of December 2022.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Breaking Down Caroline Ellison's Cooperation Agreement]]></title><description><![CDATA[Recent updates to the federal court docket for Samuel Bankman-Fried's pending criminal case over the past week revealed that the former FTX CEO has elected to enter a plea not-guilty to all 8 counts he's currently facing.

According to the updated co...]]></description><link>https://librehash.xyz/breaking-down-caroline-ellisons-cooperation-agreement</link><guid isPermaLink="true">https://librehash.xyz/breaking-down-caroline-ellisons-cooperation-agreement</guid><category><![CDATA[Blockchain]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[Bitcoin]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Sat, 21 Jan 2023 07:57:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674285830844/c2fdc70d-8134-4253-af45-710a3d4cbdbe.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recent updates to the federal court docket for Samuel Bankman-Fried's pending criminal case over the past week revealed that the former FTX CEO has elected to enter a plea <strong>not-guilty</strong> to all 8 counts he's currently facing.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210477285-5f3ae3b5-6c35-41d9-8a50-8202896e4d21.png" alt="image" /></p>
<p>According to the updated court docket, the trial is slated to take place in October of this year (2023), and is estimated to last anywhere between 2-4 weeks.</p>
<p>The next court hearing is scheduled to occur on May 18th, 2023, which will, again, be in New York (<em>SBF is flying from his parents' home in California directly to New York to attend each of these court hearings in person</em>).</p>
<h2 id="heading-in-the-absence-of-a-plea-agreement-sbf-is-likely-fucked"><strong>In the Absence of a Plea Agreement, SBF is Likely Fucked</strong></h2>
<p>What screws Samuel Bankman-Fried in this instance is the fact that Caroline Ellison and Gary Wang have not only pleaded guilty, but agreed to <strong>cooperate with federal prosecutors</strong> in their pursuit of Sam Bankman-Fried as well.</p>
<p>While the announcement itself came with tons of news coverage, few entities took the time to dissect the nature of the plea/cooperation agreement that was signed by Caroline Ellison. Even fewer outlets made accurate, logical deductions about how this would impact things for Sam Bankman-Fried and his federal case moving forward.</p>
<h2 id="heading-close-read-of-the-caroline-ellison-cooperation-agreement">Close-Read of the Caroline Ellison Cooperation Agreement</h2>
<p>To shore up these gaps in coverage, we're going to take a direct look at the agreement that was published by the SDNY, which can also be found here at this link (<em>courtesy of CNBC</em>).</p>
<p><strong>See Below</strong>:</p>
<p><a target="_blank" href="https://fm.cnbc.com/applications/cnbc.com/resources/editorialfiles/2022/12/21/1671676065196-Caroline_Ellison_Plea_Agreement.pdf"><img src="https://user-images.githubusercontent.com/59129716/210478357-3a7ed9fe-a8aa-44bd-9d99-6c8cfd1f53db.png" alt="https://fm.cnbc.com/applications/cnbc.com/resources/editorialfiles/2022/12/21/1671676065196-Caroline_Ellison_Plea_Agreement.pdf" /></a></p>
<blockquote>
<p>Please note that the image above hyperlinked to CNBC's publication of the Caroline Ellison's cooperation agreement.</p>
</blockquote>
<p><strong>The excerpt above from Caroline's cooperation agreement with federal authorities outlines several directives she must follow in order to successfully fulfill her responsibility under the agreement:</strong></p>
<ol>
<li><p>"<em>The defendant shall truthfully and completely disclose all information concerning all matters which this Office inquires, which can be used for any purpose</em>"</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall cooperate fully with this Office, the Federal Bureau of Investigation, and any other law enforcement agency designated by this Office.</em>"</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall attend all meetings requested by this Office</em>."</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall provide to this Office, upon request, any document, record, or other tangible evidence relating to matters about which this Office or any designated law enforcement agency inquires.</em>"</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall truthfully testify before the grand jury and at any trial and any other court proceeding when requested to do so by this Office.</em>"</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall bring to this Office's attention all crimes that the defendant has committed, and all administrative, civil, or criminal proceedings, investigations, or prosecutions in which the defendant has been or is a subject, target, party, or witness.</em>"</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall commit no further crimes whatsoever.</em>"</p>
</li>
<li><p>"[<strong>Caroline Ellison</strong>] <em>shall provide notice to this Office before discussing the conduct covered by the Information with anyone other than this Office, law enforcement agencies designated by this Office, and the defendant's attorney. Moreover, any assistance the defendant may provide to federal criminal investigators shall be pursuant to the specific instructions and control of this Office and designated investigators.</em>"</p>
</li>
</ol>
<p>If you're wondering what's "in it" for her, that's explained in the following paragraph in the cooperation agreement (<em>also shown below</em>):</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210479016-bc553217-18ea-4c07-9014-ff98fd762611.png" alt="image" /></p>
<p><strong>The brick of text above from the cooperation agreement outlines numerous assurances and potential benefits for Caroline Ellison upon the successful fulfillment duties as outlined in this cooperation agreement (*</strong>explained below<strong>*)</strong>:</p>
<ul>
<li><p>The DOJ states that they cannot grant Caroline blanket immunity from any future tax-related prosecutorial actions for any of her conduct related to these proceedings, the agreement is careful to note that, "<strong>if the defendant</strong> [<em>Caroline Ellison</em>] <strong>fully complies with the understandings specified in this Agreement, no testimony or other information given by the defendant (or any other information directly or indirectly derived therefrom) will be used against the defendant in any criminal tax prosecution</strong>". That quoted statement encompasses the DOJ's promise to Caroline that her expected cooperation will effectively exempt her from facing future criminal prosecution for any and all tax-related crimes she may have committed in her capacity as the CEO of Alameda + working with Sam Bankman-Fried.</p>
</li>
<li><p>The cooperation agreement also states, "<strong>if the defendant fully complies with the understandings specified in this Agreement, the defendant will not be further prosecuted criminally by this Office for any crimes, except for criminal tax violations, related to her participation in (1) a conspiracy to commit wire fraud and wire fraud on customers of FTX between in or about 2019 and in or about November 2022, as charged in Counts One and Two of the Information (2) a conspiracy to commit wire fraud and wire fraud on lenders of Alameda Research between</strong>..." and on it goes. Essentially what the prosecution is saying here is that Caroline Ellison need not fear facing further punitive measures against her that are initiated by the Department of Justice as it pertains to practically <strong>anything she did in her role(s) at FTX / Alameda</strong>.</p>
</li>
</ul>
<p>In laymen's terms, what this all means is that if she cooperates fully and gives the DOJ everything they're looking for on top of helping them obtain a guilty verdict for Samuel Bankman-Fried, she'll be able to <strong>walk away from this situation without having to spend a day in any correctional facility.</strong></p>
<p>Obviously, there's <em>some hyperbole</em> here in stating that she can "<em>walk away</em>" from this situation, but when comparing this fate outlined by the DOJ in her cooperation agreement to what she <strong>could've otherwise faced, it'</strong>s safe to assume that Caroline likely considers this that outcome to be as close to 'walking away' as anyone could hope to get after pleading guilty to multiple different federal crimes that carry an aggregate maximum of 110 years in prison.</p>
<h3 id="heading-can-caroline-really-get-off-scott-free"><strong>Can Caroline Really Get Off Scott Free?</strong></h3>
<p>Hell yeah.</p>
<p>Federal prosecutors effectively stated as much in the cooperation agreement (<em>almost verbatim</em>).</p>
<p>Check it out below:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/210479903-3ff1fe0f-c0e5-4fda-9049-45b46009b10e.png" alt="image" /></p>
<p><strong>Here's the statement we want to key in on from the excerpt above</strong>: "<em>This Agreement does not provide any prosecution against prosecution for any crimes</em> <strong>except as set forth above</strong>."</p>
<p>Confused?</p>
<p><strong>Here's the Translation</strong>:<em>This agreement essentially guarantees Caroline protection against prosecution for every crime she may have committed or plead guilty to in connection with these proceedings so long as she faithfully carries out her duties as outlined in this cooperation agreement.</em></p>
<p>The agreement does go on to note that, "<em>It is understood that this Agreement does not bind any federal, state, or local prosecuting authority other than this Office."</em> But they counter this limitation with a promise to, "<em>Bring the cooperation of the defendant to the attention of other prosecuting offices, if requested by the defendant.</em>"</p>
<p><strong>In laymen's terms, the prosecution is essentially saying</strong>: <em>We can't provide blanket immunity for the defendant in a manner that extends to all every other jurisdiction, we'd be more than happy to exert our influence to assist Ms. Ellison in resolving any future attempts to levy criminal sanctions against her for her conduct related to these proceedings, assuming the successful fulfillment of her duties as outlined by this cooperation agreement.</em></p>
<p>The reason for such a generous offer? </p>
<p><strong>She's going to be the nail in the coffin for Samuel Bankman-Fried</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Bitcoin Price Analysis - 2023 Edition (First One)]]></title><description><![CDATA[It's been a little while since we've had a chance to look at the price trajectory of Bitcoin. Ever since the implosion of FTX & Alameda, the markets were thrown in a flux, so we absconded from our charting duties for a little while.
But now that the ...]]></description><link>https://librehash.xyz/bitcoin-price-analysis-2023-edition-first-one</link><guid isPermaLink="true">https://librehash.xyz/bitcoin-price-analysis-2023-edition-first-one</guid><category><![CDATA[Bitcoin]]></category><category><![CDATA[Cryptocurrency]]></category><category><![CDATA[crypto]]></category><category><![CDATA[bitcoin price]]></category><category><![CDATA[Bitcoin Market]]></category><dc:creator><![CDATA[Cryptomedication]]></dc:creator><pubDate>Sat, 14 Jan 2023 01:48:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1673660761921/a798fb3d-a715-48be-80a1-a9a0d78fed03.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It's been a little while since we've had a chance to look at the price trajectory of Bitcoin. Ever since the implosion of FTX &amp; Alameda, the markets were thrown in a flux, so we absconded from our charting duties for a little while.</p>
<p>But now that the markets are back, we're going to make sure that we capture <strong>every single opportunity out there</strong> so that we <strong>miss nothing</strong> on the price action's ascent from this point going forward.</p>
<h3 id="heading-taking-a-look-at-how-we-forecasted-bitcoin-previously">Taking a Look at How We Forecasted Bitcoin Previously</h3>
<p>Below is a look at how we forecasted Bitcoin's price action before the SBF debacle:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212425433-dc24cbae-3604-4f6b-9768-79828580cffd.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/zfZiKf5L/">https://www.tradingview.com/x/zfZiKf5L/</a></p>
</blockquote>
<p>As we can see, we were expecting Bitcoin to at least touch the overhead horizontal resistance at $22.3k. However, that did not happen, as the price fell sharply downward after the news of FTX's bankruptcy shocked the entire cryptocurrency space.</p>
<p>That event marked the <strong>3rd black swan</strong> in just 2.5 years. Those events are:</p>
<ol>
<li><p>Global Pandemic / Stock Market Crash in March 2020</p>
</li>
<li><p>Terra Ecosystem Collapse in May 2022</p>
</li>
<li><p>FTX + Alameda Collapse</p>
</li>
</ol>
<p>Despite these setbacks (and the fact that two of them came in the space of 6 months), the price of Bitcoin never dipped much further south than $16k.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212425956-3c95b70f-e554-41ee-a013-e5bdd7cc8d00.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/lyeWOOIl/">https://www.tradingview.com/x/lyeWOOIl/</a></p>
</blockquote>
<p>One <strong>could</strong> consider those two touches to be indicative of a 'double bottom' (the chart pattern looks like a 'W').</p>
<p>This would be a <strong>fair assessment to make</strong> since these two touches followed a long-term downtrend in price.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212426423-3140b0f5-7279-4ea3-a0cc-fc8fce610fdc.png" alt="image" /></p>
<p><img src="https://user-images.githubusercontent.com/59129716/212426446-dafe82dc-32a3-49f4-9cac-9ed8ca67ac9b.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.investopedia.com/terms/d/doublebottom.asp">https://www.investopedia.com/terms/d/doublebottom.asp</a></p>
</blockquote>
<p>Here are a few examples of what the chart formation looks like:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212426560-b0900efd-3c70-4771-af76-186e646f1ddd.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://school.stockcharts.com/doku.php?id=chart_analysis:chart_patterns:double_bottom_reversal">https://school.stockcharts.com/doku.php?id=chart_analysis:chart_patterns:double_bottom_reversal</a></p>
</blockquote>
<p>Since then, we've seen the price action break through the former horizontal overhead resistance at $17.2k a few days ago on January 9th, 2023.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212426992-ea9b6dca-0e11-4ded-b372-335a4260bbc6.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/Aq6KoM4D/">https://www.tradingview.com/x/Aq6KoM4D/</a></p>
</blockquote>
<p>Since then, the price has been on a near-vertical trajectory, smashing through one of the overhead horizontal resistance points that we outlined at the $18.8k-19k mark.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212427151-1ebf516f-3d72-4127-a827-9f4a131dfc98.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/1TYqpF3P/">https://www.tradingview.com/x/1TYqpF3P/</a></p>
</blockquote>
<p>This breakout was fueled by a 15%+ price burst over the past three days from the time of writing.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212427353-e92c3bb9-b93d-4602-b62a-5f04854d7474.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/80GCFxiZ/">https://www.tradingview.com/x/80GCFxiZ/</a></p>
</blockquote>
<p>This is especially remarkable when considering how little volatility was expressed in the price action.</p>
<h3 id="heading-where-is-bitcoins-price-going-from-here">Where is Bitcoin's Price Going From Here?</h3>
<p>Now that we're all caught up on what happened, let's see if we can't track down where the price of Bitcoin is going from here.</p>
<p>In order to create this forecast, we're going to start by looking at the next resistance point ahead for the price.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212428192-6924ab98-45bb-45ad-a5df-6c1b262244b8.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/avpJjgW7/">https://www.tradingview.com/x/avpJjgW7/</a></p>
</blockquote>
<p><strong>Resistance Doesn't Mean Guaranteed Stop</strong></p>
<p>As we noted prior, Bitcoin's price blew through two overhead horizontal resistance points as if they weren't even there. And when we look at the current price action for Bitcoin on the daily resolution, it doesn't appear as though this overhead resistance point will serve as a significant impediment to price action going forward.</p>
<h2 id="heading-momentum-indicators-for-bitcoin">Momentum Indicators for Bitcoin</h2>
<p>For those that don't know, there are two different types of technical indicators that can be applied to any chart's price action in order to gather information for forecasts or understanding about how the price got to where it was at a given point in time.</p>
<blockquote>
<p><em>The other two types of indicators are referred to as 'lagging' and 'coincident'; the latter is rarely used, but we'll get into that later as needed</em></p>
<p><em>Each momentum indicator we'll take a look at here is a custom indicator coded by Librehash and disseminated with members of the Discord</em> (sometimes access is given for free if you're in the Telegram at the right time)</p>
</blockquote>
<h3 id="heading-librehash-balance-of-power-rsi">Librehash Balance of Power RSI</h3>
<p><strong>Brief Review</strong>:</p>
<ol>
<li><p>This indicator is built from the Balance of Power</p>
</li>
<li><p>We take the values of the Balance of Power, then apply the RSI extraction to it (14 periods)</p>
</li>
<li><p>From there, we smoothed the values over with the Exponential Moving Average (EMA; 9 Periods)</p>
</li>
<li><p>Then I threw on an ob/os (overbought / oversold) overlay on the chart, coded in the math logic to bound the range (similar to how RSI has a top range of 100 and lower bound of 0)</p>
</li>
<li><p>Took the average of the values over a certain period of time (manually; not via code), then calculated one standard deviation above and below that average to create the ob/os zones for the indicator</p>
</li>
<li><p>Added in logic to color the indicator red every time a period ends with the BoP RSI beyond the ob/os range to show an "<strong>extreme</strong>" in the buy/sell pressure</p>
</li>
</ol>
<p><strong>Main Purpose</strong>: <em>To detect buy &amp; sell pressure</em> (very accurately)</p>
<p>Below, is a look at what the BoP RSI is showing us on the daily resolution for Bitcoin:</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212429898-4f1aefb3-2124-461a-9b53-df1c08358615.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/brTMkGFU/">https://www.tradingview.com/x/brTMkGFU/</a></p>
</blockquote>
<p>As we can see the BoP RSI reading is well above and beyond the RSI-like overlay, which means that the buy pressure is in the <strong>extreme range</strong>.</p>
<p><strong>Does This Mean That the Price is Guaranteed to Decrease From Here?</strong></p>
<p>No, not by any means. There are many traders that have the mistaken belief that when an oscillator shows measurements outside of the norms reflected by a bounded range (<em>like the purple overlay we see in the chart above</em>), that a reversal is bound to occur due to some sort of invisible market force that seeks 'equilibrium' above all.</p>
<p>However, that is <strong>not true</strong>. While the indicator itself will likely return within the bounded RSI overlay range, that doesn't mean that the price will follow suit. Sometimes a cooldown in the indicator only means a reduction in the price's momentum (<em>which is expected since this current rate of change in the price is unsustainable</em>), not necessarily that the price will <strong>depreciate</strong>.</p>
<p>With that being said, let's see what the other indicators are showing us.</p>
<h3 id="heading-librehash-rsi14">Librehash RSI(14)</h3>
<p>This is another custom indicator, just like the one before it. This is read just like the regular RSI(14). The only difference here is that the indicator itself (line) changes colors on the basis of whether the exponential moving average of the rate of change of the RSI(14) has surpassed/fell below a slower exponential moving average of the rate of change (<em>if that's confusing, go ahead and check out how the indicator is defined on TradingView underneath the 'librehash' profile</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212430746-c5312b27-7a1a-4cd1-9380-07ca8441bacd.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/cIaDIF4f/">https://www.tradingview.com/x/cIaDIF4f/</a></p>
</blockquote>
<p>Like the Balance of Power RSI, we can see that the RSI(14) has reached <strong>far</strong> into the OB (overbought) zone.</p>
<p>The same can be ascertained of the Volatility RSI as well.</p>
<h2 id="heading-bitcoin-on-the-weekly-resolution">Bitcoin on the Weekly Resolution</h2>
<p>Since we want to get a better gauge for what Bitcoin will do in the long term, we're going to go ahead and shift over to the weekly resolution to see how the indicators are measuring Bitcoin's price action.</p>
<h3 id="heading-second-look-at-the-librehash-rsi14">Second Look at the Librehash RSI(14)</h3>
<p><img src="https://user-images.githubusercontent.com/59129716/212431127-c0e290f3-4839-4b0a-aa42-6c2aa7d94cf5.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/STyuh8cK/">https://www.tradingview.com/x/STyuh8cK/</a></p>
</blockquote>
<p>As we can see, the RSI(14) has <strong>only recently</strong> flipped to 'green', indicating that the current rate of change in the price's momentum has begun to pick up (<em>the indicator is coded to help detect</em> <strong>true changes</strong> <em>in the price action rather than getting caught in the mix by intermittent whipsaw action</em>).</p>
<p>There's obviously plenty of room for the RSI(14) to grow from where we're at on the weekly resolution, as the indicator is <strong>far below</strong> even coming close to breaching the 'overbought' range. Some technical analysis theory suggests that the RSI(14) does not dictate a true change in price momentum until it crosses above/below a reading of '50'.</p>
<p>At the time of writing, its currently at 47.58 on our RSI(14).</p>
<p>Let's take another look at Bitcoin so we can assess the last time it's given us this measurement on the weekly resolution.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212431683-399e4a2c-e034-4d07-9861-4443d649f834.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/pF9agBuu/">https://www.tradingview.com/x/pF9agBuu/</a></p>
</blockquote>
<p>Taking another look at the RSI(14), we can see that it has increased steadily from June 2022 to the present (&gt;6 months).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212431893-658025f1-c95b-464d-ab6b-a5f01163753e.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/idoIXkuS/">https://www.tradingview.com/x/idoIXkuS/</a></p>
</blockquote>
<p>There have, of course, been periods when the RSI(14) dipped substantially. But overall, the RSI(14) has trended positively from June 2022 to where we are at present. This is notable because Bitcoin has not experienced a stretch of positive RSI(14) movement since March 2020 (<em>following the first black swan we discussed above</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212432120-0ad85efe-a445-4e08-bd2b-acb4776e16b7.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/fga3kAqg/">https://www.tradingview.com/x/fga3kAqg/</a></p>
</blockquote>
<p>Of course, we know what happened to Bitcoin's price trajectory from that point.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212432314-6548516e-58aa-45ec-a651-0d4a51aaeaa7.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/sELeu2cY/">https://www.tradingview.com/x/sELeu2cY/</a></p>
</blockquote>
<p>As we can see, the price of Bitcoin increased by &gt;1100% from that point going forward.</p>
<p>What's different about this time, however, is that the RSI(14) has shown <strong>significant positive divergence</strong> over these past 6 months (<em>this was not the case during the March 2020 pivot</em>).</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212432630-1760bbb9-09cf-4833-a1cc-ea0e78812044.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/2hux2jsE/">https://www.tradingview.com/x/2hux2jsE/</a></p>
</blockquote>
<h3 id="heading-what-does-positive-divergence-mean-for-the-rsi">What Does Positive Divergence Mean for the RSI?</h3>
<p>A lot in our case. To refresh ourselves, let's take a brief look at Investopedia's definition of 'divergence' within the context of technical analysis.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212432809-4572e2dc-0850-4273-b334-3662ff39c9e6.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.investopedia.com/terms/d/divergence.asp">https://www.investopedia.com/terms/d/divergence.asp</a></p>
</blockquote>
<p>As shown above, Investopedia accurately indicates that there is 'positive and negative divergence' and that, "<em>positive divergence indicates a move higher in the price of the asset is possible</em>".</p>
<p>In this case, we are indeed seeing positive divergence since the oscillator/indicator has <strong>trended upward</strong> as the <strong>price has declined</strong>.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212432951-d9193638-ac9a-4f53-b63b-464fb2a3f445.png" alt="image" /></p>
<p>When such divergence occurs on the <strong>weekly resolution</strong>, we should take it <strong>seriously</strong>. The larger the time frame, the more substantial the forecast as it pertains to the price trajectory going forward.</p>
<h2 id="heading-riskreward-target">Risk/Reward Target</h2>
<p>For this forecast, we're going to use the EMA indicators to give us a sense for where we should expect any notable resistance for the price moving forward.</p>
<p>To do so, we plotted the EMA 12,26,50,100 &amp; 200. Currently, the price has surpassed the EMA-12 (purple). It appears it'll blast through the EMA-26. Beyond that, the EMA-50 (<em>gold</em>) is hanging out at around $25k.</p>
<p>So we're going to plot that as our target for our R/R. We'll plot $18.8k as our stop-out point since such a decline would warrant a <strong>strong reconsideration</strong> of our position.</p>
<p><img src="https://user-images.githubusercontent.com/59129716/212434185-668cf4ed-f09d-4566-b965-b6e1af74e1c4.png" alt="image" /></p>
<blockquote>
<p><a target="_blank" href="https://www.tradingview.com/x/vVUPoVGJ/">https://www.tradingview.com/x/vVUPoVGJ/</a></p>
</blockquote>
<p>That's a potential +27.74% reward, with a risk of approximately -5% from where we're at currently. We can live with that R/R for sure (<em>always risk management!</em>)</p>
<p>If we get stopped out, we'll just manage our position from there and decide whether we're going to elect to re-enter or not.</p>
]]></content:encoded></item></channel></rss>