<?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Defendor]]></title><description><![CDATA[Web3 security made easy — real bugs, audit tactics, career. Weekly.]]></description><link>https://defendor.xyz</link><image><url>https://substackcdn.com/image/fetch/$s_!se8H!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b39055-c35a-4243-86aa-3ca7b0c72202_1280x1280.png</url><title>Defendor</title><link>https://defendor.xyz</link></image><generator>Substack</generator><lastBuildDate>Sun, 19 Apr 2026 10:13:04 GMT</lastBuildDate><atom:link href="https://defendor.xyz/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Defendor. Web3 Security]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[defendor@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[defendor@substack.com]]></itunes:email><itunes:name><![CDATA[Arsen]]></itunes:name></itunes:owner><itunes:author><![CDATA[Arsen]]></itunes:author><googleplay:owner><![CDATA[defendor@substack.com]]></googleplay:owner><googleplay:email><![CDATA[defendor@substack.com]]></googleplay:email><googleplay:author><![CDATA[Arsen]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Auditor's golden system]]></title><description><![CDATA[Write notes like this. Find more bugs.]]></description><link>https://defendor.xyz/p/how-auditors-make-notes</link><guid isPermaLink="false">https://defendor.xyz/p/how-auditors-make-notes</guid><dc:creator><![CDATA[Arsen]]></dc:creator><pubDate>Mon, 30 Mar 2026 18:02:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/dcf9617f-7033-440c-aef2-ff416907a939_967x640.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, it&#8217;s Arsen.</p><p>In today&#8217;s menu:<br>&#8226; The note-taking system most auditors skip<br>&#8226; USR token minted and dumped &#8212; price crashed to $0.05<br>&#8226; And more&#8230;</p><div><hr></div><p><strong>&#127988;&#8205;&#9760;&#65039; Hacks / Bounties<br>&#8226; USR token minted and dumped &#8212; price crashes to $0.05 (<a href="https://t.me/defendor_eng/1375">Link</a>)<br>&#8226; Auto-allocation bug turned USR exploit into bad debt (<a href="https://t.me/defendor_eng/1379">Link</a>)</strong></p><p><strong>&#128478;&#65039; News<br>&#8226; BattleChain testnet lets whitehats attack contracts pre-mainnet (<a href="https://t.me/defendor_eng/1392">Link</a>)<br>&#8226; Balancer Labs winds down after exploit fallout (<a href="https://t.me/defendor_eng/1383">Link</a>)</strong></p><p><strong>&#128218; Education<br>&#8226; Why audit process matters more than findings (<a href="https://t.me/defendor_eng/1376">Link</a>)<br>&#8226; The Flashloan fee inflation bug that drained $250K on dTrinity fork (<a href="https://t.me/defendor_eng/1398">Link</a>)</strong></p><div><hr></div><h1><strong>Deep Dive</strong></h1><p>You reviewed the code line by line.</p><p>You feel like you understand it.</p><p>But can you explain it from memory?</p><p>Most auditors can&#8217;t.</p><p>And the ones who can&#8217;t &#8212; don&#8217;t know what they missed.</p><p>Here&#8217;s what happens after a typical line-by-line read.</p><p>You feel like you covered the function.</p><p>You move on.</p><p>10 functions later &#8212; you &#8220;reviewed&#8221; the whole contract.</p><p><strong>Then a senior asks: walk me through the codebase from memory.</strong></p><p>Blank.</p><p>Or worse &#8212; you trace a bug back.</p><p>And realize you skipped the exact piece that would&#8217;ve caught it.</p><p>The problem isn&#8217;t effort.</p><p>Line-by-line reading is passive.</p><p>You see the code.</p><p>You make underlying notes.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SDoZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SDoZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 424w, https://substackcdn.com/image/fetch/$s_!SDoZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 848w, https://substackcdn.com/image/fetch/$s_!SDoZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 1272w, https://substackcdn.com/image/fetch/$s_!SDoZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SDoZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png" width="1456" height="247" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:247,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:61159,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://defendor.xyz/i/192457525?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SDoZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 424w, https://substackcdn.com/image/fetch/$s_!SDoZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 848w, https://substackcdn.com/image/fetch/$s_!SDoZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 1272w, https://substackcdn.com/image/fetch/$s_!SDoZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F447c625f-0cc6-40f8-b01f-e16a24990819_1518x258.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>That&#8217;s not the same as understanding it.</p><p>Writing a lot pushes understanding.</p><p>When you explain something in your own words and get stuck &#8212;</p><p>That&#8217;s not failure.</p><p>That&#8217;s the system working.</p><div class="pullquote"><p><strong>The stuck = gap = where the bug usually lives.</strong></p></div><p>Most auditors ignore that moment and keep moving.</p><p><strong>The ones who find criticals stop, follow the thread, and write down what they find.</strong></p><p>Here&#8217;s the process I use, function by function:</p><ul><li><p>Open a new note named after the function. Write the sub-structure first (flows/ideas). Skeleton before detail.</p></li><li><p>Explain every line in your own words &#8212; not quoted, explained. What does it do? Who provides this value? Who can control it?</p></li><li><p>When you catch yourself not understanding &#8212; stop immediately. Open the constructor. Write what you find. Link back. Continue.</p></li><li><p>Log attack leads in-place. When a &#8220;what if&#8221; hits, write it right there. Tag it [DOS?] [Access?]. Write the theory. Confirm or disprove it. Don&#8217;t let it disappear into your head.</p></li><li><p>Don&#8217;t fear rabbit holes. Your notes hold the context &#8212; your brain doesn&#8217;t have to. Go as deep as needed. You won&#8217;t lose the thread.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Wc7F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Wc7F!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 424w, https://substackcdn.com/image/fetch/$s_!Wc7F!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 848w, https://substackcdn.com/image/fetch/$s_!Wc7F!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 1272w, https://substackcdn.com/image/fetch/$s_!Wc7F!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Wc7F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png" width="1456" height="619" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:619,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101235,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://defendor.xyz/i/192457525?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Wc7F!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 424w, https://substackcdn.com/image/fetch/$s_!Wc7F!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 848w, https://substackcdn.com/image/fetch/$s_!Wc7F!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 1272w, https://substackcdn.com/image/fetch/$s_!Wc7F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92ba414e-7a52-4ad2-aef9-ca1ec8b322aa_2182x928.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here&#8217;s how it played out in a recent audit.</p><p>I was going through a reconstitute function.</p><p>Wrote: &#8220;governor checks the sender is trusted.&#8221;</p><p>Caught myself &#8212; who is governor? Where is it set?</p><p>Jumped to the constructor.</p><p>No validation on the input.</p><p>Wrote it down.</p><p>That one caught thread became a finding.</p><p>The function looked clean on first read.</p><p>The notes found the bug.</p><p>Most auditors treat notes as documentation.</p><p>A record of what they saw.</p><p>That&#8217;s wrong.</p><div class="pullquote"><p>Notes are the audit.</p></div><p>Explaining every function in your own words, following every unclear thought &#8212;</p><p>That IS the process that finds bugs.</p><p>By the time you&#8217;ve written detailed notes on every function, you&#8217;ve processed the protocol twice.</p><p>The gaps are documented, not buried.</p><p>The attack leads are on paper, waiting to be tested.</p><p>Re-read in 20 minutes what took 4 hours to build &#8212; and see it fresh.</p><p>Arsen.</p><div class="poll-embed" data-attrs="{&quot;id&quot;:485505}" data-component-name="PollToDOM"></div><p>Reply with what you want me to cover next &#8212; I read every one.</p>]]></content:encoded></item><item><title><![CDATA[Pre-Quoted. Not Safe.]]></title><description><![CDATA[Most people missed this. Here's exactly what was wrong.]]></description><link>https://defendor.xyz/p/pre-quoted-not-safe</link><guid isPermaLink="false">https://defendor.xyz/p/pre-quoted-not-safe</guid><dc:creator><![CDATA[Arsen]]></dc:creator><pubDate>Mon, 23 Mar 2026 16:36:49 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/62377928-b1ba-47a3-b767-953146d860b5_1048x690.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, it&#8217;s Arsen.</p><p>In today&#8217;s menu:</p><ul><li><p>Full CTF answer &#8212; the reconstitute bug, completely broken down</p></li><li><p>Why off-chain quoting is a repeatable Medium finding pattern</p></li><li><p>And more&#8230;</p></li></ul><div><hr></div><p>&#127988;&#8205;&#9760;&#65039; <strong>Hacks / Bounties</strong></p><ol><li><p><strong>$50M Aave Swap &#8212; Extreme Price Impact (<a href="https://t.me/defendor_eng/1346">Link</a>)</strong></p></li><li><p><strong>Venus Protocol &#8212; $2.18M Bad Debt (<a href="https://t.me/defendor_eng/1353">Link</a>)</strong></p></li><li><p><strong>dTRINITY Flash Loan &#8212; $257K Drained (<a href="https://t.me/defendor_eng/1356">Link</a>)</strong></p></li></ol><p><strong>&#128478;&#65039; News</strong></p><ol><li><p><strong>Solana Audit Arena Launched (<a href="https://t.me/defendor_eng/1354">Link</a>)</strong></p></li><li><p><strong>Shutter DAO &#8212; Governance Attack Prevented (<a href="https://t.me/defendor_eng/1362">Link</a>)</strong></p></li></ol><p><strong>&#128217; Education</strong></p><ol><li><p><strong>War Room Playbook for Onchain Hacks (<a href="https://t.me/defendor_eng/1359">Link</a>)</strong></p></li><li><p><strong>AI Auditing: 47% Detection, 0% Exploit Success (<a href="https://t.me/defendor_eng/1366">Link</a>)</strong></p></li></ol><div><hr></div><h3>Last Week&#8217;s CTF &#8212; Full Answer</h3><p>Most replies mentioned slippage.</p><p>A few said stale pricing.</p><p>Almost nobody got the exact mechanism.</p><p>Here it is.</p><p>The contract runs two phases.</p><p><strong>Phase 1: Sell every holding into base.</strong></p><p>Simple. Approve the DEX, call the swap, measure the delta. <code>baseReceived</code> builds up across every holding.</p><p><strong>Phase 2: Buy new assets using base.</strong></p><pre><code><code>for (uint256 j; j &lt; newAssets.length;) {
    Token(base).approve(dex, allocateAmounts[j]);
    (bool ok,) = dex.call(buyData[j]);
    require(ok);
    unchecked { ++j; }
}
</code></code></pre><p>One question changes everything:</p><p>Where does <code>allocateAmounts</code> come from?</p><pre><code><code>function reconstitute(
    ...
    uint256[] calldata allocateAmounts
)
</code></code></pre><p>It&#8217;s an input param.</p><p>Passed in from an off-chain entity &#8212;</p><p>a bot, a governor script, some automation.</p><p>That off-chain entity did this:</p><p>Called a view function on the DEX.</p><p>Simulated how much base Phase 1 would produce.</p><p>Built <code>allocateAmounts</code> from that simulation.</p><p>Then triggered <code>reconstitute</code>.</p><p><strong>The gap:</strong></p><p>The view call happens before execution.</p><p>Actual execution happens later.</p><p>Prices move in between.</p><p>Price moves up &#8212; contract receives more base than expected.</p><p>Phase 2 completes. Leftover base sits unspent, unaccounted.</p><p>Price moves down &#8212; contract receives less base than expected.</p><p>Phase 2 tries to spend <code>allocateAmounts</code>.</p><p>Doesn&#8217;t have enough. Swap fails. Transaction reverts.</p><p>DoS.</p><p>That&#8217;s a Medium.</p><p>The question that catches it every time:</p><p>&#8220;Is the amount I&#8217;m spending in Phase 2 guaranteed to match what I received in Phase 1?&#8221;</p><p>If <code>allocateAmounts</code> comes from outside the contract &#8212;</p><p>no guarantee.</p><p><strong>The fix:</strong></p><p>Validate onchain before Phase 2 runs:</p><pre><code><code>uint256 totalNeeded;
for (uint256 j; j &lt; allocateAmounts.length;) {
    totalNeeded += allocateAmounts[j];
    unchecked { ++j; }
}
require(baseReceived &gt;= totalNeeded, "insufficient base");</code></code></pre><p>Or better &#8212; derive <code>allocateAmounts</code> from <code>baseReceived</code></p><p>directly inside the contract. Remove the off-chain dependency entirely.</p><p>The auditor pattern to carry forward:</p><p>When you see a value passed as calldata from an off-chain trigger &#8212; pause.</p><p><strong>Ask three things:</strong></p><ul><li><p>Where was this calculated?</p></li><li><p>When was it calculated?</p></li><li><p>Can the state it referenced change before execution?</p></li></ul><p>&#8220;Pre-quoting&#8221; gives the off-chain system confidence.</p><p>But confidence at quote time isn&#8217;t safety at execution time.</p><p>You&#8217;ll see this in:</p><ul><li><p>Portfolio rebalancers (this one)</p></li><li><p>AMM-based yield strategies</p></li><li><p>Cross-chain transfers with off-chain routing</p></li></ul><p>Any system where automation pre-computes amounts</p><p>and passes them in as params.</p><p>Every time &#8212; ask the same three questions.</p><p>Simple question. Consistent Medium. Sometimes High.</p><p>Arsen</p><div class="poll-embed" data-attrs="{&quot;id&quot;:481313}" data-component-name="PollToDOM"></div><p>Reply with what you want me to cover next &#8212; I read every one.</p>]]></content:encoded></item><item><title><![CDATA[Where the Money Went?]]></title><description><![CDATA[Why blind calldata forwarding breaks DeFi vaults]]></description><link>https://defendor.xyz/p/where-the-money-went</link><guid isPermaLink="false">https://defendor.xyz/p/where-the-money-went</guid><dc:creator><![CDATA[Arsen]]></dc:creator><pubDate>Thu, 19 Mar 2026 18:01:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!se8H!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b39055-c35a-4243-86aa-3ca7b0c72202_1280x1280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This week we talked about how contests changed and why you need sharper attacking instincts.</p><p>Time to test yours.</p><p><code>BasketRebalancer</code> is an on-chain index fund.</p><p>It holds ERC-20 tokens weighted by basis points.</p><p>A governor can rebalance the basket</p><p>by selling holdings into <code>base</code>,</p><p>then buying new assets.</p><p>Find the vulnerability.</p><p>Answer will be dropped next Monday &#128293;</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;javascript&quot;,&quot;nodeId&quot;:&quot;796ad020-ff98-41b7-ade6-24be7c9a0d84&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-javascript">// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract SimpleDex {
    address public owner;
    uint256 public rate = 1e18;

    constructor() { owner = msg.sender; }

    function setRate(uint256 r) external { require(msg.sender == owner); rate = r; }

    function swap(address tIn, address tOut, uint256 amtIn, address to) external returns (uint256 out) {
        Token(tIn).transferFrom(msg.sender, address(this), amtIn);
        out = (amtIn * rate) / 1e18;
        require(out &gt; 0);
        Token(tOut).transfer(to, out);
    }
}

contract BasketRebalancer {
    uint256 constant BPS = 10_000;

    address public governor;
    address public base;
    address public dex;
    address[] public holdings;
    uint256[] public bps;

    constructor(address _gov, address _base, address _dex) {
        governor = _gov; base = _base; dex = _dex;
    }

    function setComposition(address[] calldata a, uint256[] calldata b) external {
        require(msg.sender == governor);
        require(a.length == b.length &amp;&amp; a.length &gt; 0);
        uint256 t;
        for (uint256 i; i &lt; b.length;) { require(b[i] &gt; 0); t += b[i]; unchecked { ++i; } }
        require(t == BPS);
        holdings = a; bps = b;
    }

    function deposit(address token, uint256 amount) external {
        Token(token).transferFrom(msg.sender, address(this), amount);
    }

    function rebalance(
        address[] calldata newAssets,
        uint256[] calldata newBps,
        bytes[]   calldata sellData,
        bytes[]   calldata buyData,
        uint256[] calldata allocateAmounts
    ) external {
        require(msg.sender == governor);
        require(newAssets.length == newBps.length &amp;&amp; newAssets.length &gt; 0);
        require(buyData.length == newAssets.length);
        require(allocateAmounts.length == newAssets.length);

        uint256 t;
        for (uint256 i; i &lt; newBps.length;) { require(newBps[i] &gt; 0); t += newBps[i]; unchecked { ++i; } }
        require(t == BPS);

        // Phase 1: sell all current holdings &#8594; base
        uint256 baseReceived;
        for (uint256 i; i &lt; holdings.length;) {
            address asset = holdings[i];
            uint256 bal = Token(asset).balanceOf(address(this));
            if (bal &gt; 0) {
                if (asset == base) {
                    baseReceived += bal;
                } else {
                    uint256 before = Token(base).balanceOf(address(this));
                    Token(asset).approve(dex, bal);
                    (bool ok,) = dex.call(sellData[i]);
                    require(ok);
                    baseReceived += Token(base).balanceOf(address(this)) - before;
                }
            }
            unchecked { ++i; }
        }

        // Phase 2: buy new assets with base
        if (baseReceived &gt; 0) {
            for (uint256 j; j &lt; newAssets.length;) {
                Token(base).approve(dex, allocateAmounts[j]);
                (bool ok,) = dex.call(buyData[j]);
                require(ok);
                unchecked { ++j; }
            }
            holdings = newAssets;
            bps = newBps;
        }
    }
}</code></pre></div>]]></content:encoded></item><item><title><![CDATA[You understand the code. Now what?]]></title><description><![CDATA[That's not the end. That's the starting line.]]></description><link>https://defendor.xyz/p/you-understand-the-code-now-what</link><guid isPermaLink="false">https://defendor.xyz/p/you-understand-the-code-now-what</guid><dc:creator><![CDATA[Arsen]]></dc:creator><pubDate>Mon, 16 Mar 2026 16:01:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/149fbdae-15ff-4d59-bbac-302d2cdead66_1480x970.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>&#127988;&#8205;&#9760;&#65039; <strong>Hacks / Bounties</strong></p><ul><li><p><strong>Aave wstETH Oracle Error &#8212; $21M in Unfair Liquidations</strong> (<a href="https://t.me/defendor_eng/1330">Link</a>)</p></li><li><p><strong>DBXen ERC2771 Exploit &#8212; $150K Loss</strong> (<a href="https://t.me/defendor_eng/1334">Link</a>)</p></li><li><p><strong>Alkemi Self-Liquidation &#8212; $90K Loss</strong> (<a href="https://t.me/defendor_eng/1329">Link</a>)</p></li></ul><p>&#128478;&#65039; <strong>News</strong></p><ol><li><p><strong>Ethereum Bug Bounty Raised to 1M</strong> (<a href="https://t.me/defendor_eng/1327">Link</a>)</p></li><li><p><strong>Safe Zodiac Roles Permission Bypass</strong> (<a href="https://t.me/defendor_eng/1325">Link</a>)</p></li></ol><p>&#128217; <strong>Education</strong></p><ol><li><p><strong>9 Common Vault Bugs &#8212; Real Audit Findings </strong>(<a href="https://t.me/defendor_eng/1271">Link</a>)</p></li><li><p><strong>ERC-4337 Account Abstraction Security Risks </strong>(<a href="https://t.me/defendor_eng/1331">Link</a>)</p></li></ol><div><hr></div><h1>Deep Dive</h1><p>That&#8217;s not the end. That&#8217;s the starting line.</p><p>We&#8217;re not programmers. We don&#8217;t write much code.</p><p>We read it. Every day. That&#8217;s the job.</p><p>Nobody teaches you how to read code properly.</p><p>You grind courses, collect tools, study vulnerabilities.</p><p>But the skill senior auditors do 80% of the day?</p><p>Reading code fast and deeply.</p><p>Most people are terrible at it.</p><h2><strong>The problem</strong></h2><p>Here&#8217;s what beginners do.</p><p>They open the codebase. Open the docs.</p><p>50 pages of specs and architecture diagrams.</p><p>Page 5 &#8212; overwhelmed.</p><p>Page 10 &#8212; lost the thread.</p><p>Haven&#8217;t touched a single line of code.</p><p>Or worse &#8212; they jump into one function.</p><p>Go deep immediately. Lose the whole system&#8217;s context.</p><p>Waste 3 hours on something that doesn&#8217;t matter.</p><p>Then they say:</p><div class="pullquote"><p>&#8220;I understand the code. I found nothing.&#8221;</p></div><p>No. You didn&#8217;t understand the code. You just read it.</p><p>The bugs are still sitting there.</p><p><strong>The real problems:</strong></p><ul><li><p><strong>Docs first = overwhelm before you even start</strong></p></li><li><p><strong>Going deep too early = wasted time</strong></p></li><li><p><strong>&#8220;No bugs found&#8221; = you stopped at understanding</strong></p></li><li><p><strong>No system = random scanning, random results</strong></p></li></ul><h2><strong>The 3 layers</strong></h2><p>Code reading has 3 layers.</p><p>Most auditors only do 1 or 2.</p><p><strong>Layer 1: Skim &amp; Contextualize.</strong></p><p>Grab the big picture. Jump into the code. Not docs.</p><p><strong>Layer 2: Deep Read &amp; Memorize.</strong></p><p>Go line by line. Walk the entire flow in your head</p><p>without looking at the screen.</p><p><strong>Layer 3: Research.</strong></p><p>This is where bugs actually live.</p><p>NOW read the docs. Compare to reality.</p><p>Study other protocols. Work backwards from failure modes.</p><p>Here&#8217;s the game-changer:</p><p>AI accelerates Layer 1 massively.</p><p>Feed it each function. Get line-by-line comments.</p><p>Ask it to explain flows above each function.</p><p>You get context 10x faster &#8212; and save that time for Layer 3.</p><p>Most auditors stop after Layer 2.</p><p>The ones finding criticals? They live in Layer 3.</p><h2><strong>The playbook</strong></h2><p><strong>LAYER 1: SKIM &amp; CONTEXTUALIZE</strong></p><ul><li><p>Jump into code first. Not docs. </p></li><li><p>Skim every function without going deep.</p></li><li><p>Identify entry points, libraries, integrations, main actors.</p></li><li><p>Use AI as your co-pilot here:</p></li></ul><p>feed each function &#8594; get comments &#8594; map the flows.</p><ul><li><p>This is orientation. Not understanding yet.</p></li></ul><div class="pullquote"><p>Common mistake: reading 50 pages of docs before touching code.</p></div><p>You&#8217;ll lose context before you start.</p><p><strong>LAYER 2: DEEP READ &amp; MEMORIZE</strong></p><ul><li><p>Go function by function, line by line.</p></li><li><p>For each critical function: what it validates,</p></li></ul><p>who can call it, what state it changes.</p><ul><li><p>The goal: close the editor.</p></li></ul><p>Explain the entire flow from memory.</p><ul><li><p>If you get stuck &#8212; do another pass.</p></li><li><p>~50% of your audit time = Layer 1 + Layer 2.</p></li></ul><p>Common mistake: moving to &#8220;bug hunting&#8221;</p><p>before you can explain the system from memory.</p><p><strong>LAYER 3: RESEARCH (where bugs live)</strong></p><ul><li><p>Read the docs NOW.</p></li></ul><p>Compare every claim to the code. Contradictions = bugs.</p><ul><li><p>List developer assumptions. Ask: &#8220;What if this is wrong?&#8221;</p></li><li><p>Study how other protocols solve the same problem.</p></li><li><p>Research every error in try-catch blocks.</p></li><li><p>Work backwards: all failure modes &#8594; eliminate what can&#8217;t happen</p></li></ul><p>&#8594; what survives is your attack surface.</p><p>Common mistake: treating &#8220;I understand the code&#8221;</p><p>as the finish line instead of the starting line.</p><p>Timeline for a 10-day engagement:</p><ul><li><p>Days 1&#8211;2: Layer 1 &#8212; skim, map, use AI</p></li><li><p>Days 2&#8211;5: Layer 2 &#8212; deep read, memorize</p></li><li><p>Days 5&#8211;10: Layer 3 &#8212; research, docs, comparisons</p></li></ul><p>Arsen</p><div class="poll-embed" data-attrs="{&quot;id&quot;:472394}" data-component-name="PollToDOM"></div><p>Reply with what you want me to cover next &#8212; I read every one.</p>]]></content:encoded></item><item><title><![CDATA[How to approach contests in 2026]]></title><description><![CDATA[How to approach contests correctly]]></description><link>https://defendor.xyz/p/how-to-approach-contests-in-2026</link><guid isPermaLink="false">https://defendor.xyz/p/how-to-approach-contests-in-2026</guid><dc:creator><![CDATA[Arsen]]></dc:creator><pubDate>Mon, 02 Mar 2026 17:01:10 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/086414c2-5bad-40b1-b14b-831321706ff5_1476x982.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, it&#8217;s Arsen.</p><p>In today&#8217;s menu:</p><ul><li><p>Why the old contest playbook is dead &#8212; and the 3 shifts that replaced it</p></li><li><p>$10.8M oracle hack, $150K live contest, AI finds a Uniswap bug</p></li><li><p>What to do before your next contest (most skip this)</p></li></ul><p></p><p><strong>Best links this week:</strong></p><p>&#127988;&#8205;&#9760;&#65039; <strong>YieldBlox drained for $10.8M via oracle manipulation</strong> &#8594; <a href="https://github.com/DK27ss/YieldBlox-10M-PoC">link</a></p><p>&#127988;&#8205;&#9760;&#65039; <strong>Guardian drops $150K AMM contest &#8212; LimitBreak</strong> &#8594; <a href="https://defender.guardianaudits.com/contests/6998a6cf6a508136784689d0">link</a></p><p>&#128478;&#65039; <strong>Uniswap V4 bug found via AI-assisted auditing</strong> &#8594; <a href="https://x.com/i/status/2025848523724312609">link</a></p><p>&#128217; <strong>Zellic: Inside the SVM &#8212; sBPF JIT pitfalls</strong> &#8594; <a href="https://www.zellic.io/blog/solana-sbpf/">link</a></p><p></p><h1>Deep dive</h1><p>Everyone says contests are dead.</p><p>Everyone says junior auditors are cooked.</p><p>Here&#8217;s the truth: no one knows.</p><p>There&#8217;s only opinions. And one fact.</p><p>The complexity bar is rising.</p><p>Forget about weird ERC20 tokens.</p><p>In 2021, people earned good money on simple bugs. Set up firms. Called themselves auditors.</p><p>In reality &#8212; intermediate at best.</p><p>When I jumped in during 2024, it was harder. Bugs weren&#8217;t trivial. But there were still plays. Dummy bugs earning $20K+.</p><p>Now? One way forward.</p><p>Prove you can find deep bugs in business logic.</p><p>But here&#8217;s what most people miss.</p><p>Contests aren&#8217;t dead.</p><p>The old approach to contests is dead.</p><p>&#8220;Jump in, learn on the go, find some bugs, get paid.&#8221;</p><p>That worked 1-2 years ago. Not anymore.</p><p>A contest in 2026 is a test.</p><p>A test for auditors hungry enough to adapt.</p><p>Less &#8220;animals&#8221; to hunt. So you change the strategy.</p><p></p><p>Here&#8217;s what actually works now:</p><h3><strong>1. Combine forces.</strong></h3><p>Why hunt alone?</p><p>Find 2-3 hungry auditors. Build a system for gathering project context fast.</p><p>That&#8217;s what eats your time &#8212; understanding, not hunting.</p><p>The mistake juniors make: rushing to submit.</p><p>Low-hanging fruit gets duplicated by 200 people. Real bugs hide deeper. You need research time after you already understand the system.</p><p></p><h3><strong>2. Use AI for understanding. Not hunting.</strong></h3><p>AI makes you dumb if you let it.</p><p>Critical thinking is the one skill you must develop. </p><p>Without it &#8212; $1 leaderboard auditor forever.</p><p>Use AI to gain context faster. Not to find the bugs.</p><p>The best AI usage comes from seniors who know what to aim it at. </p><p>If you&#8217;re junior, don&#8217;t overrely.</p><p></p><h3><strong>3. Specialize in one domain.</strong></h3><p>Early on, I jumped from contest to contest. </p><p>Cross-chain. AMM. Lending.</p><p>Nothing stuck.</p><p>Now? Pick one domain.</p><p>AMM contest dropping in 2 weeks?</p><p>Grind hard on AMM knowledge, bugs, patterns. Show up prepared. Not hoping. Prepared.</p><p>And treat every contest as compound interest.</p><p>Low payouts? You&#8217;re building the muscle.</p><p>Pattern recognition. Speed. Domain knowledge.</p><p>30 contests with small wins will crush quitting after 3.</p><p>After each one &#8212; write a 5-line retro.</p><p>What you found. What you missed. What you&#8217;d change.</p><p>That&#8217;s your personal edge database.</p><p>Stop measuring success by payout alone.</p><p>The real ROI is the skill compounding.</p><p>This newsletter gives you the direction.</p><blockquote><p>But the full system &#8212; team audit setups, contest prep workflows, domain specialization paths, weekly live Q&amp;As where I break down exactly how I approach each contest &#8212; that&#8217;s what we build inside <a href="https://www.skool.com/defendor">Defendor Academy.</a></p></blockquote><p>If you want to stop guessing and start winning, everything you need is there. <a href="https://www.skool.com/defendor">[link]</a></p><p>See you there</p>]]></content:encoded></item><item><title><![CDATA[Top-1 Must-Have Skill for Security Researchers]]></title><description><![CDATA[This one is significant. If You believe you&#8217;ve found all the bugs &#8212; and you stop early, you've failed]]></description><link>https://defendor.xyz/p/top-1-must-have-skill-for-security</link><guid isPermaLink="false">https://defendor.xyz/p/top-1-must-have-skill-for-security</guid><dc:creator><![CDATA[Arsen]]></dc:creator><pubDate>Sun, 08 Feb 2026 14:48:46 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/79430712-15f0-4c94-ae9b-a70d3bc41c08_1234x760.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This one is significant.</p><p>Play close attention.</p><p>Since it destroys <strong>80%</strong> of auditors, including ones with a strong track record.</p><p>It&#8217;s simple:</p><blockquote><p>You believe you&#8217;ve found all the bugs &#8212; and you stop early.</p></blockquote><p>This is the most common self-inflicted mistake in Web3 security.</p><p>Not because you&#8217;re unskilled.</p><p>But because your brain wants comfort.</p><p>Auditing is mentally hard.</p><p>You stare at the same lines for hours.</p><p>You stretch your mind to generate new attack angles again and again.</p><p>And the moment you <em>feel</em> like you&#8217;ve &#8220;made progress,&#8221; your brain tries to convince you:</p><p>&#8220;Good job. Enough. You&#8217;re done.&#8221;</p><p>This is the trap.</p><p>And there is only one rule that breaks it:</p><blockquote><p><em><strong>Bugs always exist. Hunt until the last second.</strong></em></p></blockquote><p>Remember it.</p><p>Stick it into your audit identity.</p><p><em><strong>This rule alone will change your entire progress curve &#8212; because it forces your brain to stay in attacker mode instead of comfort mode.</strong></em></p><p>And 2025 proved this point brutally well.</p><p>Balancer &#8212; broken.</p><p>GMX &#8212; broken.</p><p>After years of operation.</p><p>After multiple audits.</p><p>After thousands of eyes.</p><p>And you still think a 3-4 week audit means &#8220;everything is covered&#8221;?</p><p>Let me show you the moment that permanently completely changed me.</p><p>Early 2025.</p><p>I was collaborating with very well known audit firm</p><p>This specific audit was conducted by use a 2x2 structure:</p><p>Two auditors vs two auditors, competing on the same repo.</p><blockquote><p><em><strong>It&#8217;s one of the most effective ways to boost curiosity, aggression, and pace during an audit.</strong></em></p></blockquote><p>But the strongest part isn&#8217;t the competition.</p><p>It&#8217;s the scoreboard.</p><p>You can&#8217;t see the issues themselves &#8212; but you <em>can</em> see how many H/M/L the other team has found.</p><p>Now picture this.</p><p>Last day of the audit.</p><p>I slowed down.</p><p>I <em>thought</em> the repo was empty. I convinced myself that the hard bugs were already found.</p><p>Then a message pops up:</p><blockquote><p>&#8220;Other team is 1H ahead.&#8221;</p></blockquote><ul><li><p>Instant adrenaline.</p></li><li><p>Instant humiliation.</p></li><li><p>Instant clarity.</p></li></ul><p>I closed everything I was doing &#8212; restaurant, cinema, didn&#8217;t matter &#8212;</p><p>opened my laptop and hunted like an animal.</p><h3>Example <strong><a href="https://www.notion.so/Mismatch-Between-Redemption-Calculation-and-Available-Margin-20bb02576124814b9e12c1c85973bb83?pvs=21">link</a></strong></h3><p>To understand this bug, you need just <strong>one idea</strong>:</p><p><strong>Collateral and PnL are updated through different mechanisms.</strong></p><ul><li><p><strong>Collateral</strong> updates through:<code>modifyCollateral()</code> or <code>_settleOrder()</code></p></li><li><p><strong>PnL</strong> updates <em>only</em> when you call:<code>_settleOrder()</code></p></li></ul><p>Meaning:</p><blockquote><p>Your collateral does NOT include PnL until you commit-settle.</p></blockquote><p>But the vault&#8217;s <code>redeem</code> logic assumes the opposite.</p><p><strong>Where Things Break</strong></p><p>The redeem flow calls <code>_valueToRedeem()</code>:</p><pre><code><code>valueToRedeem = totalAssets() * (shares / totalSupply)</code></code></pre><p>And here&#8217;s the problem:</p><p><code>totalAssets()</code><em><strong> includes PnL &#8212; even if it&#8217;s NOT settled yet.</strong></em></p><p>So the vault uses <strong>unrealized, un-settled PnL</strong> as if it already exists as collateral.</p><p>Then, during actual withdrawal, the vault calls <code>modifyCollateral</code>:</p><ul><li><p><code>modifyCollateral</code> works with <strong>real collateral tokens only</strong></p></li><li><p>It <strong>cannot</strong> withdraw unrealized PnL (because it&#8217;s not collateral yet)</p></li></ul><p>This creates a mismatch.</p><p>And every single time similar push, I found something I would&#8217;ve missed if I relaxed.</p><p>This is the truth nobody wants to admit:</p><blockquote><p><em><strong>If you want to grow, you must hunt actively &#8212; until the last second. Not until you&#8217;re comfortable. Until the code is empty.</strong></em></p></blockquote><p>This is the difference between plateaus and breakthroughs.</p><p>Between $2k bugs and $200k bugs.</p><p>Between staying mid and becoming senior.</p>]]></content:encoded></item></channel></rss>