<?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[Offside Labs’ Security Insights]]></title><description><![CDATA[Penetrate the cutting edge of web3 security with the elite researchers at Offside Labs.]]></description><link>https://blog.offside.io</link><image><url>https://substackcdn.com/image/fetch/$s_!RcIR!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb871fb7-47b7-4301-a9dc-ad0500f02941_130x130.png</url><title>Offside Labs’ Security Insights</title><link>https://blog.offside.io</link></image><generator>Substack</generator><lastBuildDate>Wed, 08 Apr 2026 20:52:15 GMT</lastBuildDate><atom:link href="https://blog.offside.io/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Offside Labs]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[offsidelabs@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[offsidelabs@substack.com]]></itunes:email><itunes:name><![CDATA[Offside Labs]]></itunes:name></itunes:owner><itunes:author><![CDATA[Offside Labs]]></itunes:author><googleplay:owner><![CDATA[offsidelabs@substack.com]]></googleplay:owner><googleplay:email><![CDATA[offsidelabs@substack.com]]></googleplay:email><googleplay:author><![CDATA[Offside Labs]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Token-2022 Security Best Practices - Part 2: Extensions]]></title><description><![CDATA[Without a solid understanding of tokens, projects face serious risks. This post highlights the extensions of Token-2022 that need closer security attention, reveals issues and provides suggestions to safeguard users and project funds.]]></description><link>https://blog.offside.io/p/token-2022-security-best-practices-part-2</link><guid isPermaLink="false">https://blog.offside.io/p/token-2022-security-best-practices-part-2</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Mon, 04 Nov 2024 10:22:38 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L-6P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L-6P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 424w, https://substackcdn.com/image/fetch/$s_!L-6P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 848w, https://substackcdn.com/image/fetch/$s_!L-6P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!L-6P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L-6P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png" width="614" height="460.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:1012552,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L-6P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 424w, https://substackcdn.com/image/fetch/$s_!L-6P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 848w, https://substackcdn.com/image/fetch/$s_!L-6P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!L-6P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2a8f4dc-9d1e-4aea-ab1f-00b05e887a8a_1600x1200.png 1456w" sizes="100vw" fetchpriority="high"></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><h1>Recap</h1><p>Welcome back to Token-2022 Security Best Practices. In <em><strong><a href="https://blog.offside.io/p/token-2022-security-best-practices-part-1">Part 1</a></strong></em>, we addressed the potential security issues associated with Mint and Token Accounts when supporting <em><strong><a href="https://spl.solana.com/token-2022">Token-2022</a></strong></em>. In this part, we will explore the <em><strong>extensions of Token-2022</strong></em>, analyze potential security risks, and suggest recommended solutions. Please pay close attention to each topic, especially the <em><strong>Attention</strong></em> section.</p><h1>How to hedge the security risks of Token-2022 Extensions</h1><p>Token-2022 expands the functionality of mint and token accounts compatible with SPL Token through an extension model. It introduces nearly 20 <em><strong><a href="https://spl.solana.com/token-2022/extensions">Extensions</a></strong></em>. If developers lack sufficient understanding of the assumptions and characteristics of these extensions, serious security issues, such as DoS or financial losses, may arise.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>In this chapter, we will explore five Token-2022 extensions closely related to security, summarize their security assumptions, and outline potential security issues associated with these extensions.</p><h2>1. Metadata, Group &amp; Member</h2><p>Token-2022 includes three metadata extensions to describe mint, along with three corresponding pointer extensions that pair with each of these metadata extensions.</p><p>Pointer extensions, which ensure that data accessed through the pointer is valid and trusted, are stored within the extension part of mint account. Data, however, are more flexible&#8212;they can reside either within the extension part of mint account or as a separate account.</p><p>If a contract or DApp requires the data from <em><strong><a href="https://spl.solana.com/token-2022/extensions#metadata">Metadata</a>, <a href="https://spl.solana.com/token-2022/extensions#group">Group</a></strong></em>, or <em><strong><a href="https://spl.solana.com/token-2022/extensions#member">Member</a></strong></em>, it is essential for the project team to verify the authenticity of the data, which depends on the <em><strong>mutual reference relationship</strong></em> between the data and the pointer.</p><h3>Attention</h3><blockquote><p>Everyone can create Token-2022 accounts of type Metadata, Group and Group Member, fill these accounts with deliberately crafted data, and point them to a legitimate mint. However, only the metadata accounts that mint&#8217;s pointer references are considered authoritative and verified by itself. </p><p>The following diagram illustrates the expected relationship between Metadata and Metadata Pointer. There is a Mint A and its corresponding Metadata M here:</p><ul><li><p>A.metadata_pointer.metadata_address == M</p></li><li><p>M.mint == A</p></li></ul></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sDLz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sDLz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 424w, https://substackcdn.com/image/fetch/$s_!sDLz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 848w, https://substackcdn.com/image/fetch/$s_!sDLz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!sDLz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sDLz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png" width="614" height="429.71565934065933" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1019,&quot;width&quot;:1456,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:225947,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sDLz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 424w, https://substackcdn.com/image/fetch/$s_!sDLz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 848w, https://substackcdn.com/image/fetch/$s_!sDLz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!sDLz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a7014b2-33b4-452b-b0b0-61ef1d015e80_3143x2200.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></p><blockquote><p>Token-2022 allows mint creators to embed their token&#8217;s Metadata, Group and Member data directly into the mint account to simplify the use of data. In this case, the relationship diagram can be simplified as follows:</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Vt-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Vt-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 424w, https://substackcdn.com/image/fetch/$s_!1Vt-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 848w, https://substackcdn.com/image/fetch/$s_!1Vt-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 1272w, https://substackcdn.com/image/fetch/$s_!1Vt-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Vt-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png" width="210" height="514.5892351274788" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2595,&quot;width&quot;:1059,&quot;resizeWidth&quot;:210,&quot;bytes&quot;:156273,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1Vt-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 424w, https://substackcdn.com/image/fetch/$s_!1Vt-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 848w, https://substackcdn.com/image/fetch/$s_!1Vt-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.png 1272w, https://substackcdn.com/image/fetch/$s_!1Vt-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe132dea6-d5e8-4b74-b682-11d2e99b8579_1059x2595.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><h2>2. Permanent Delegate</h2><p>Token-2022 introduces a high-risk extension to the mint account: <em><strong><a href="https://spl.solana.com/token-2022/extensions#permanent-delegate">Permanent Delegate</a></strong></em>.</p><p>The authority designated as a permanent delegate holds <em><strong>high privileges</strong></em> to <em><strong>directly transfer or burn any amount of mint</strong></em> from any token account.</p><p>For instance, in the implementation of SPL Token-2022&#8217;s <em><strong>process_transfer</strong></em> function, when verifying the transfer authority, the permanent delegate is automatically authorized without further checks.</p><pre><code>    pub fn process_transfer(
        ...
    ) -&gt; ProgramResult {
        ...
        match (source_account.base.delegate, maybe_permanent_delegate) {
            (_, Some(ref delegate)) if cmp_pubkeys(authority_info.key, delegate) =&gt; {
                Self::validate_owner(
                    program_id,
                    delegate,
                    authority_info,
                    authority_info_data_len,
                    account_info_iter.as_slice(),
                )?
            }
        ...
    }</code></pre><p>This diagram summarizes three types of transfer scenarios:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hXmu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hXmu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 424w, https://substackcdn.com/image/fetch/$s_!hXmu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 848w, https://substackcdn.com/image/fetch/$s_!hXmu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 1272w, https://substackcdn.com/image/fetch/$s_!hXmu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hXmu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png" width="614" height="492.54945054945057" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1168,&quot;width&quot;:1456,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:742739,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hXmu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 424w, https://substackcdn.com/image/fetch/$s_!hXmu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 848w, https://substackcdn.com/image/fetch/$s_!hXmu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.png 1272w, https://substackcdn.com/image/fetch/$s_!hXmu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44d96541-1c1b-4072-9d6d-d9884c7ba6a8_3724x2988.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><ul><li><p>A standard transfer initiated directly by the authority of the source token account</p></li><li><p>A transfer initiated by a delegate account, previously approved by the authority of the source token account</p></li><li><p>A transfer initiated by the permanent delegate account, bypassing the need for a signature from the authority of the source token account</p></li></ul><h3>Attention</h3><blockquote><p>Both developers and users need to be particularly concerned at mints that include Permanent Delegate. It is important to closely monitor and manage the actions of the permanent delegate to avoid unexpected losses due to their high privileges.</p><p>As a developer, it is vital to clearly define and describe the permissions and security policies linked to the permanent delegate role in projects involving mints with this extension. The high-privilege operations of this role must not be misused. Additionally, implementing monitoring for this role is recommended to provide timely alerts and prevent unforeseen actions.</p><p>As a user, it is necessary to be aware of whether your asset's mint supports a Permanent Delegate. We strongly recommend you to transfer assets to this mint only after confirming that the delegate authority can be fully trustworthy.</p></blockquote><h2>3. Memo Transfer</h2><p><em><strong><a href="https://spl.solana.com/token-2022/extensions#required-memo-on-transfer">Memo Transfer</a></strong></em> is a new Token-2022 extension that allows users to enable memos on their token accounts, enabling them to view memos attached to transfers when receiving tokens.</p><p>The Token-2022 program requires that the transfer IX must be<code> </code><em><strong>immediately preceded</strong></em> by a Memo IX when processing a Memo-enabled destination token account.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MtgG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MtgG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 424w, https://substackcdn.com/image/fetch/$s_!MtgG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 848w, https://substackcdn.com/image/fetch/$s_!MtgG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 1272w, https://substackcdn.com/image/fetch/$s_!MtgG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MtgG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png" width="238" height="382.21854304635764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:970,&quot;width&quot;:604,&quot;resizeWidth&quot;:238,&quot;bytes&quot;:62729,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MtgG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 424w, https://substackcdn.com/image/fetch/$s_!MtgG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 848w, https://substackcdn.com/image/fetch/$s_!MtgG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.png 1272w, https://substackcdn.com/image/fetch/$s_!MtgG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7bfefbf-a2c9-47ff-b74e-8b05018c36d5_604x970.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>This is the code snippet from the SPL transfer related to memo. If the IX immediately preceding the transfer is not a memo, the SPL transfer will result in an error.</p><pre><code>    pub fn process_transfer(
        ...
    ) -&gt; ProgramResult {
        ...
        if memo_required(&amp;destination_account) {
            check_previous_sibling_instruction_is_memo()?;
        }
        ...
    }</code></pre><h3>Attention</h3><blockquote><p>As a protocol developer, if your contract supports Token-2022 transfers, you&#8217;ll consider whether to handle by ensuring a Memo IX added before each Transfer IX for memo-enabled token accounts or not. Otherwise, if a memo-enabled token account is used as a destination account, the transfer process will fail, potentially disrupting protocol&#8217;s functionality and effecting user experience.</p></blockquote><h2>4. Interest-Bearing Tokens</h2><p><em><strong><a href="https://spl.solana.com/token-2022/extensions#interest-bearing-tokens">Interest-Bearing Tokens</a> </strong></em>is an extension in Token-2022 that pertains to token interests and UI amount. By using this extension in combination with the <em><strong><a href="https://solana-labs.github.io/solana-program-library/token/js/functions/amountToUiAmount.html">AmountToUiAmount</a></strong></em> and <em><strong><a href="https://solana-labs.github.io/solana-program-library/token/js/functions/uiAmountToAmount.html">UiAmountToAmount</a></strong></em> instructions, developers can convert between raw amounts and UI amounts.</p><h3>Attention</h3><p><strong>Hardcoded Formula</strong></p><p>This extension uses a fixed formula to calculate interests based on the <em><strong>timestamp</strong></em>. The extension cannot be applied when the interests calculation formula expected by developers for this mint differs from it or the interests is calculated based on a unit except the timestamp (e.g., based on slots).</p><p>For example, when converting the raw amount to the UI amount, the following formula is utilized in the extension:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;ui\\_amount = amount * (\\frac{e^{\\frac{R_\n{pre} * (T_{last} - T_{init})}{\\frac{31556736}{10000}}} * e^{\\frac{R_{current} * (T_{current} - T_{last})}{\\frac{31556736}{10000}}}}{10^{decimals}} )&quot;,&quot;id&quot;:&quot;OJXRPTYTJB&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><blockquote><p>Developers need to confirm whether this is consistent with the conversion rules expected in your project or not.</p></blockquote><p><strong>Unstable Network</strong></p><p>Due to <em><strong>network instability</strong></em> on Solana (such as occasional congestion), the actual timestamp during execution may <em><strong>deviate</strong></em>, resulting in accumulated interests that may not match the expected value.</p><blockquote><p>Since the <em><strong><a href="https://solanatechroundup.hashnode.dev/solana-tech-roundup-19">Bank Timestamp Correction</a></strong></em> was updated in May 2022, clock drift issues have been significantly improved, except for timestamp jumps caused by temporary block production halts.</p></blockquote><p>In summary, developers should use this extension only after verifying that it aligns with the project&#8217;s requirements. The project should not overly rely on the conversion result provided by the IX, as it is simply a UI representation and does not guarantee consistency with the actual amount.</p><h2>5. Transfer Fees</h2><p><em><strong><a href="https://spl.solana.com/token-2022/extensions#transfer-fees">Transfer Fees</a></strong></em> is a crucial extension in Token-2022, offering built-in support for handling transfer fees.</p><p>When <em><strong>Transfer Fees</strong></em> is enabled for a Token-2022 mint, each transfer operation records its associated fee amount in the extension data of the recipient&#8217;s token account. These recorded fees are inaccessible to the recipient and are not included in the available balance of their token account.</p><p>If the mint&#8217;s <em><strong>transfer_fee_basis_points</strong></em> is greater than 0, the actual amount received by the receiver is less than the amount specified in the transfer IX after the process of transfer.</p><h3>Attention</h3><blockquote><p>If the contract calling <em><strong>transfer_checked IX </strong></em>requires additional accounting, developers must consider how to account for the transfer fee. Counting this fee as part of the amount actually received by the receivers may lead to unexpected losses in various scenarios within protocol, contract, or user accounts.</p></blockquote><p><strong>A Negative Case</strong></p><p>Let&#8217;s have a look at a simple case where a protocol fails to account for the transfer fee, leading to a loss:</p><p>The vault handles deposits and withdrawals for a Token-2022 mint with a 20% fee rate, and it currently has a balance of 1000 in its token account.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pVca!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pVca!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 424w, https://substackcdn.com/image/fetch/$s_!pVca!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 848w, https://substackcdn.com/image/fetch/$s_!pVca!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 1272w, https://substackcdn.com/image/fetch/$s_!pVca!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pVca!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png" width="1456" height="889" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0806b850-d028-4005-b541-c36868797599_4788x2924.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:889,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:579150,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pVca!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 424w, https://substackcdn.com/image/fetch/$s_!pVca!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 848w, https://substackcdn.com/image/fetch/$s_!pVca!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.png 1272w, https://substackcdn.com/image/fetch/$s_!pVca!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0806b850-d028-4005-b541-c36868797599_4788x2924.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><ul><li><p>Step 1: Alice deposits 100:</p><ul><li><p>The vault calls the transfer_checked to move 100 from Alice&#8217;s token account to the vault.</p><ul><li><p>Alice&#8217;s balance decreases by 100.</p></li><li><p>After the transfer fee is applied, the vault actually receives 80, bringing its balance to 1080.</p></li></ul></li><li><p>The vault logs Alice&#8217;s deposit as 100.</p></li></ul></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_!nxi8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nxi8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 424w, https://substackcdn.com/image/fetch/$s_!nxi8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 848w, https://substackcdn.com/image/fetch/$s_!nxi8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 1272w, https://substackcdn.com/image/fetch/$s_!nxi8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nxi8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png" width="1456" height="913" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:913,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:598376,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nxi8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 424w, https://substackcdn.com/image/fetch/$s_!nxi8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 848w, https://substackcdn.com/image/fetch/$s_!nxi8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.png 1272w, https://substackcdn.com/image/fetch/$s_!nxi8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2092f671-ea1a-4bea-973e-8f0a25d11ef6_4763x2986.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><ul><li><p>Step 2: Alice withdraws 100:</p><ul><li><p>The vault confirms Alice&#8217;s balance is at least 100 and logs her withdrawal of 100.</p></li><li><p>The vault calls the transfer_checked to send 100 from its token account back to Alice.</p><ul><li><p>After the transfer fee, Alice receives 80, increasing her balance by 80.</p></li><li><p>The vault&#8217;s balance decreases by 100, leaving it with 980.</p></li></ul></li></ul></li></ul><p>In this example, after Alice&#8217;s deposit and withdrawal, the vault ends up losing 20 units (1000 - 980 = 20). This is because the vault didn&#8217;t account for the Token-2022 transfer fee during its bookkeeping, causing an unintended loss.</p><p><strong>The Difference Between </strong><em><strong>fee</strong></em><strong> and </strong><em><strong>inverse_fee</strong></em></p><p>In a specific scenario, the program needs to utilize the <em><strong>post amount</strong></em> (after deducting the fee from original transfer amount, i.e., <em><strong>pre amount</strong></em>) to determine the fee required for the actual transfer. The SPL struct <em><strong><a href="https://docs.rs/spl-token-2022/latest/spl_token_2022/extension/transfer_fee/struct.TransferFee.html">spl_token_2022::extension::transfer_fee::TransferFee</a> </strong></em>includes methods like <em><strong><a href="https://docs.rs/spl-token-2022/latest/spl_token_2022/extension/transfer_fee/struct.TransferFee.html#method.calculate_inverse_fee">calculate_inverse_fee</a> </strong></em>and<em><strong> <a href="https://docs.rs/spl-token-2022/latest/spl_token_2022/extension/transfer_fee/struct.TransferFee.html#method.calculate_pre_fee_amount">calculate_pre_fee_amount</a></strong></em> to meet this requirement.</p><p>It is worth noting that the <em><strong><a href="https://docs.rs/spl-token-2022/latest/spl_token_2022/extension/transfer_fee/struct.TransferFee.html#method.calculate_fee">calculate_fee</a></strong></em> method in <em><strong>TransferFee</strong></em> is commonly used to compute the transfer fee for the <em><strong>transfer_checked</strong></em> IX. However, <em><strong>calculate_inverse_fee</strong></em> is not a strict inverse operation of <em><strong>calculate_fee</strong></em>. The relationship of these two operations is:</p><pre><code>calculate_fee(amount_in) &gt;= calculate_inverse_fee(amount_in - calculate_fee(amount_in)) </code></pre><blockquote><p>Here are some specific links for additional reference:</p><ul><li><p>For a detailed implementation of these functions, please check <em><strong><a href="https://github.com/solana-labs/solana-program-library/blob/c59e2f35203a38b75ab9686c4fe8d95beaf20c28/token/program-2022/src/extension/transfer_fee/mod.rs#L115-L129">this code link</a></strong></em>.</p></li><li><p>For a discussion on the relationship between these two operations, refer to <em><strong><a href="https://github.com/solana-labs/solana-program-library/pull/6874">this Github PR</a></strong></em>.</p></li></ul></blockquote><p>Here is an example dataset to illustrate the inequality mentioned above.</p><p>Let&#8217;s start by defining all input parameters that will be utilized throughout the following computation.</p><pre><code>// Transfer Amount
amount_in : 5238206430131997821

// Transfer Fee Config
transfer_fee_basis_points: 1000
maximum_fee 5704976840628159154</code></pre><p>By inputting this data into the SPL code's calculation method, the following results are obtained:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v0Xd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v0Xd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 424w, https://substackcdn.com/image/fetch/$s_!v0Xd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 848w, https://substackcdn.com/image/fetch/$s_!v0Xd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 1272w, https://substackcdn.com/image/fetch/$s_!v0Xd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v0Xd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png" width="1421" height="319" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:319,&quot;width&quot;:1421,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:28965,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v0Xd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 424w, https://substackcdn.com/image/fetch/$s_!v0Xd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 848w, https://substackcdn.com/image/fetch/$s_!v0Xd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 1272w, https://substackcdn.com/image/fetch/$s_!v0Xd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe807e970-fc7c-4ae4-a85f-ca99dd880285_1421x319.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In this example, the difference between <em><strong>calculate_fee(amount_in)</strong></em><code> </code>and <em><strong>calculate_inverse_fee(amount_in - calculate_fee(amount_in))</strong></em> is <em><strong>523820643013199783 - 523820643013199782 = 1</strong></em>. This demonstrates that the two values can indeed be <em><strong>unequal</strong></em>.</p><blockquote><p>Note: Although these two methods may yield slightly different fees, the corresponding post-amounts are identical. Which means, in the following pseudocode snippet, despite pre_amount_2 possibly is smaller than pre_amount_1, post_amount_1 and post_amount_2 are always equal:</p></blockquote><pre><code>post_amount_1 = pre_amount_1 - calculate_fee(pre_amount_1)
pre_amount_2 = calculate_pre_fee_amount(post_amount_1)
post_amount_2 = pre_amount_2 - calculate_fee(pre_amount_2)
// Despite pre_amount_2 possibly being smaller than pre_amount_1, 
post_amount_1 == post_amount_2</code></pre><p>Given this potential discrepancy, developers should<em><strong> avoid interchanging fees derived from these two methods</strong></em> to prevent unexpected issues.</p><p>If project has a specific requirement to reverse the inequality mentioned above, i.e.,</p><pre><code>calculate_fee(amount_in) &lt;= calculate_inverse_fee(amount_in - calculate_fee(amount_in)) </code></pre><p>There is one possible solution: In the <em><strong>calculate_pre_fee_amount</strong></em> method of struct <em><strong>spl_token_2022::extension::transfer_fee::TransferFee</strong></em>, adjust the algorithm for calculating <em><strong>raw_pre_fee_amount</strong></em> by modifying the calculation formula as follows:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot; raw\\_pre\\_fee\\_amount = \\frac{numerator + ONE\\_IN\\_BASIS\\_POINTS - 1}{denominator} &quot;,&quot;id&quot;:&quot;BMYUQNMXAE&quot;}" data-component-name="LatexBlockToDOM"></div><blockquote><p>For the mathematical proof,  please check the appendix at the end of this article.</p></blockquote><p><strong>The Expected Transfer Fee</strong></p><p>For contracts or users who want to ensure that the fee charged during a transfer aligns with their expectations, they can use the <em><strong>transfer_checked_with_fee IX</strong></em> provided by Token-2022.</p><p>This IX ensures that the transfer will only succeed if the correct fees are specified to help to prevent any unexpected issues during the transfer process.</p><p><strong>Transfer Fee Effective Time</strong></p><p>Token-2022 includes a security feature that delays fee configuration updates.</p><p>When a new Fee configuration is set, it doesn&#8217;t take effect immediately; instead, <em><strong><a href="https://github.com/solana-labs/solana-program-library/blob/c59e2f35203a38b75ab9686c4fe8d95beaf20c28/token/program-2022/src/extension/transfer_fee/processor.rs#L102-L109">it becomes active after 2 epochs</a></strong></em> (around 4 days). During this period, the previous fee configuration remains in place. This delay serves as a safeguard for users, protecting them from potential financial losses due to frequent fee adjustments.</p><p>For developers updating the fee configuration, it is important to keep in mind that the old fee settings will continue to apply during the 2-epoch transition period before the new settings come into effect.</p><blockquote><p>The <em><strong><a href="https://solana-labs.github.io/solana-program-library/token/js/functions/getTransferFeeConfig.html">getTransferFeeConfig</a></strong></em> IX and <em><strong><a href="https://solana-labs.github.io/solana-program-library/token/js/functions/getEpochFee.html">getEpochFee</a></strong></em> IX can be used to check the current transfer fees for a given mint in the current epoch.</p></blockquote><p><strong>The Maximum Fee</strong></p><p>The<code> </code><em><strong>maximum_fee</strong></em> sets the upper limit for the fee charged per transfer. If it is not set, the default is 0, which effectively means <em><strong><a href="https://github.com/solana-labs/solana-program-library/blob/c59e2f35203a38b75ab9686c4fe8d95beaf20c28/token/program-2022/src/extension/transfer_fee/mod.rs#L69">no fees are charged during transfers</a></strong></em>.</p><p>When configuring or updating the fee config during development, it is important to ensure that the <em><strong>maximum_fee</strong></em> is properly set.</p><p><strong>The Withheld Amount Synchronization</strong></p><p><em><strong>TransferFeeConfig.withheld_amount</strong></em> does not reflect real-time data. This value is stored in the mint account and is not automatically synchronized with the actual fees collected during transfers. Typically, the <em><strong>withheld_amount</strong></em> is less than the total transfer fees that have been collected.</p><p>You should invoke the <em><strong><a href="https://solana-labs.github.io/solana-program-library/token/js/functions/harvestWithheldTokensToMint.html">HarvestWithheldTokensToMint</a></strong></em> IX, which manually updates the withheld_amount from a group of token accounts to synchronize this value.</p><blockquote><p>This synchronization is optional.</p></blockquote><h1>Conclusion</h1><p>In this post, we highlighted several extensions that are susceptible to security issues and provided detailed information on related security considerations. </p><p>Token-2022 is still at its early stages that lacks extensive publicly available security documentation. Despite the extension capabilities in Token-2022 are quite robust, notable security risks may be come with. Since extensions are directly tied to Mint and Token Accounts, many of these risks can pose significant threats to funds of users and projects. </p><p>Throughout our research, we devoted significant effort to studying the official Token-2022 documentation and SPL source code. Recently, we came across a <em><strong><a href="https://neodyme.io/en/blog/token-2022/">blog</a> </strong></em>by <em><strong><a href="https://neodyme.io/en/">Neodyme</a></strong></em>, a well-known security research team in the Solana ecosystem, which also addressed security concerns related to Token-2022 extensions. Fortunately, many of our perspectives on the security of these extensions align with theirs. We are also looking forward to more research on Token-2022 security in the future to help the community build a more secure Solana ecosystem.</p><p>This is the second blog from Offside Labs regarding Token-2022 security best practices. Check out our last blog on: </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;3f62b27e-491d-4aaf-9010-ddc52c8d408c&quot;,&quot;caption&quot;:&quot;Introduction&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Token-2022 Security Best Practices - Part 1: Mint &amp; Token Account&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:243339513,&quot;name&quot;:&quot;Offside Labs&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6aca23d-946d-480a-bf69-91e6688bf743_800x800.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-09-19T08:17:12.165Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.offside.io/p/token-2022-security-best-practices-part-1&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:148944074,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Offside Labs&#8217; Security Insights&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb871fb7-47b7-4301-a9dc-ad0500f02941_130x130.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h1>Acknowledgements</h1><p>We would like to thank the <em><strong><a href="https://www.meteora.ag/">Meteora team</a></strong></em>, especially<em><strong> <a href="https://x.com/sudoku_defi">@sudoku_defi</a></strong></em>, for their valuable insights, which shaped the solution for calculate_inverse_fee.</p><h1>Appendix</h1><h2>Mathematical Proof for Modified <em><strong>calculate_inverse_fee</strong></em></h2><p>Given <em><strong>x</strong></em> as the <em><strong>amount_in</strong></em> of transfer_checked IX and <em><strong>r</strong></em><code> </code>as the <em><strong>transfer_fee_basis_points</strong></em>, where <code>x</code> and <code>r</code> are natural numbers satisfying 0 &lt; r &lt; 10000.</p><p>The <em><strong>post_amount</strong></em> satisfies following equation:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;post\\_amount = x - calculate\\_fee(x)&quot;,&quot;id&quot;:&quot;PTQNGZIFBH&quot;}" data-component-name="LatexBlockToDOM"></div><p>The function implementation for <em><strong>calculate_fee</strong></em> and <em><strong>calculate_inverse_fee</strong></em> can be represented as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;calculate\\_fee(x) = \\lfloor\\frac{x * r + 10000 - 1}{10000}\\rfloor&quot;,&quot;id&quot;:&quot;PJZEWRXDZU&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;calculate\\_inverse\\_fee(post\\_amount)\n&quot;,&quot;id&quot;:&quot;PBFPKXOHRB&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;=calculate\\_fee(calculate\\_pre\\_fee\\_amount(post\\_amount))&quot;,&quot;id&quot;:&quot;EAMTUUZMWJ&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>The modified <em><strong>calculate_pre_fee_amount</strong></em> can be represented as:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;calculate\\_pre\\_fee\\_amount_{modified}(post\\_amount) \n&quot;,&quot;id&quot;:&quot;IEPCPYIWQO&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n= \\lfloor\\frac{post\\_amount * 10000 + 10000 - 1}{10000 - r}\\rfloor&quot;,&quot;id&quot;:&quot;ZAHNCADRIE&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>Now let&#8217;s prove the following inequation:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\ncalculate\\_fee(x) <= calculate\\_inverse\\_fee_{modified}(x - calculate\\_fee(x))&quot;,&quot;id&quot;:&quot;PTQXHBSSYW&quot;}" data-component-name="LatexBlockToDOM"></div><p>Proof:</p><p>The inequation is:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;calculate\\_fee(x) <= calculate\\_inverse\\_fee_{modified}(x - calculate\\_fee(x)) = \n&quot;,&quot;id&quot;:&quot;COMPSTYUVI&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;= calculate\\_fee(calculate\\_pre\\_fee\\_amount_{modified}(x - calculate\\_fee(x)))&quot;,&quot;id&quot;:&quot;PEZIKLLJWZ&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p>As <em><strong>calculate_fee</strong></em> is a <em><strong>monotonically increasing</strong></em> function of <code>x</code>, the inequality to be proved can be simplified to:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\nx \\le calculate\\_pre\\_fee\\_amount_{modified}(x - calculate\\_fee(x))&quot;,&quot;id&quot;:&quot;JCZVCPHCPR&quot;}" data-component-name="LatexBlockToDOM"></div><p>The proof follows:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\because x - calculate\\_fee(x) = x - \\lfloor \\frac{x * r + 10000 -1}{10000} \\rfloor&quot;,&quot;id&quot;:&quot;KHVIETDMDL&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\\therefore calculate\\_pre\\_fee\\_amount_{modified}(x - calculate\\_fee(x))&quot;,&quot;id&quot;:&quot;DPPWKTUTMN&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n= \\lfloor \\frac{10000 * x - 10000 * \\lfloor \\frac{x * r + 10000 -1}{10000} \\rfloor + 10000 -1}{10000 - r} \\rfloor&quot;,&quot;id&quot;:&quot;UFMBQVPSOY&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\ge \\lfloor \\frac{10000 * x - 10000 *  \\frac{x * r + 10000 -1}{10000} + 10000 -1}{10000 - r} \\rfloor&quot;,&quot;id&quot;:&quot;HMQVLWXNGI&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n= \\lfloor \\frac{10000 * x - x * r}{10000 - r} \\rfloor&quot;,&quot;id&quot;:&quot;QOSVAPDNUO&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;= \\lfloor \\frac{10000 * x - x * r}{10000 - r} \\rfloor&quot;,&quot;id&quot;:&quot;XYEYZTPDTH&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;= \\lfloor x * \\frac{10000 - r}{10000 - r} \\rfloor&quot;,&quot;id&quot;:&quot;GXZPFMJAOJ&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n= x &quot;,&quot;id&quot;:&quot;YJOMDIQTOJ&quot;}" data-component-name="LatexBlockToDOM"></div><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;\n\\square&quot;,&quot;id&quot;:&quot;UBRRPSFVST&quot;}" data-component-name="LatexBlockToDOM"></div><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Token-2022 Security Best Practices - Part 1: Mint & Token Account]]></title><description><![CDATA[This is the first article in the Token-2022 Security Best Practices series. It discusses potential security vulnerabilities in Mint and Token Accounts during Solana development when supporting Token-2022 and offers recommended design and implementation strategies.]]></description><link>https://blog.offside.io/p/token-2022-security-best-practices-part-1</link><guid isPermaLink="false">https://blog.offside.io/p/token-2022-security-best-practices-part-1</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Thu, 19 Sep 2024 08:17:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rY1y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rY1y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rY1y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 424w, https://substackcdn.com/image/fetch/$s_!rY1y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 848w, https://substackcdn.com/image/fetch/$s_!rY1y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!rY1y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rY1y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png" width="614" height="460.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1092,&quot;width&quot;:1456,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:1000532,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rY1y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 424w, https://substackcdn.com/image/fetch/$s_!rY1y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 848w, https://substackcdn.com/image/fetch/$s_!rY1y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!rY1y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a04b1c-d108-442d-ac27-a46ec34eaa96_1600x1200.png 1456w" sizes="100vw" fetchpriority="high"></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><h1>Introduction</h1><p>As <em><strong><a href="https://solana.com/">Solana</a></strong></em> continues to evolve, users' demands for sophisticated and flexible token functionalities are growing. However, <em><strong><a href="https://spl.solana.com/token">Token</a></strong></em> on Solana have so far only provided basic functionalities, which are unable to meet this increasing demand.</p><p>In response, Solana has introduced <em><strong><a href="https://spl.solana.com/token-2022">Token-2022</a></strong></em>, a suite of enhanced features designed to expand token capabilities within the ecosystem. Token-2022 is fully compatible with the existing SPL Token and extends native token features through nearly 20 Token Extensions.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>There is not much publicly available material on the types of security issues. The purpose of this series of articles is to shed light on the secure development, helping Solana developers avoid potential security risks while implementing support for Token-2022.</p><p>This first article of our series will discuss the following 3 topics. And we hope you can pay extra attention to the <em><strong>Attention</strong></em> section in each topic.</p><ul><li><p>Security risks across various stages of Account Lifetime</p></li><li><p>Commonly confused terms between SPL Token and Token-2022</p></li><li><p>Best practices for securely using Token-2022 in Anchor</p></li></ul><h1>How to secure accounts during its whole lifetime?</h1><p>Following the design principles of <code>Solana Account Model</code>, the extensions in Token-2022 are built around the <code>Token Account</code> and <code>Mint Account</code>. Throughout the various stages of these Account Lifetimes, there exist several security risks to which developers must pay attention during both the design and implementation phases. We will illustrate these risks for <code>Token Account</code> and <code>Mint Account</code> respectively.</p><h2>1. Token Account </h2><p>As for the Token Accounts, the essential difference between Token-2022 and SPL Token is the addition of the extension data.</p><p>In terms of implementation, Token-2022 serves as a proper superset of SPL Token, maintaining the structural layout of Token Accounts while appending additional fields of Extension Data to the original Token Account. </p><p>The general structure is depicted as follows. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!szTt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!szTt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 424w, https://substackcdn.com/image/fetch/$s_!szTt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 848w, https://substackcdn.com/image/fetch/$s_!szTt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 1272w, https://substackcdn.com/image/fetch/$s_!szTt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!szTt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png" width="180" height="371.2903225806452" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1151,&quot;width&quot;:558,&quot;resizeWidth&quot;:180,&quot;bytes&quot;:74059,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!szTt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 424w, https://substackcdn.com/image/fetch/$s_!szTt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 848w, https://substackcdn.com/image/fetch/$s_!szTt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.png 1272w, https://substackcdn.com/image/fetch/$s_!szTt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb88af2a-fd7c-4846-a6ce-2364c64ddd4f_558x1151.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 is a list with the extensions that could be appended to Token Account&#65306;</p><ul><li><p>Immutable Owner</p></li><li><p>CPI Guard</p></li><li><p>Required Memo on Transfer</p></li><li><p>Non-Transferable Tokens</p></li><li><p>Transfer Fees</p></li><li><p>Transfer Hook</p></li><li><p>Confidential Transfer</p></li><li><p>Confidential Transfer Fee</p></li></ul><p>We will examine the three stages of the Token Account lifecycle: creation, reallocation, and closure.</p><p>At each stage, there are potential security risks that developers should be aware of.</p><h3>1.1. The Creation of Token Account</h3><p>The size of Token Account in Token-2022 <em><strong>CAN</strong></em> differ from that of SPL Token, depending on the types and number of Extensions supported by the Mint and Token Account. Different sizes of Token Accounts will be created based on the number of Extensions supported. These accounts can take up more space than those in SPL Token, and their size will grow as additional extensions are added.</p><h4>Attention</h4><blockquote><p>It is <code>not recommended</code> to <code>hardcode a fixed space size </code>for the Token Account or the minimum rent-exempt amount that the fixed space size requires, if you need to create a Token-2022 Token Account for a user at the runtime.</p></blockquote><h4>Vulnerable Case</h4><p>The function below allows a Keeper to dynamically create a Token Account with Token-2022 support.</p><pre><code>export const getCostToOpenTokenAccount = async () =&gt; {
  const cost = 0.00203928 * (10 ** 9);
  return cost;
};</code></pre><p>A hardcoded SOL amount of <code>0.00203928</code> is used when creating the Token Account, which matches the rent needed for the <em>165 bytes</em> required by a Token Account in the Token Program. </p><p>The problem arises when this Token Account needs to support Token-2022 extensions: the specified amount is <em>insufficient</em> to cover the extra space needed by Token-2022 account extensions, then the creation of Token Account will fail.</p><p>If the space size is determined by the user and the Backend Keeper is responsible for creating the Token Account, there will be a potential risk of the Keeper overpaying rent, resulting in financial losses.</p><p>Therefore, it is recommended to avoid having the Keeper create Token Accounts for users.</p><h4>Recommendation</h4><p>The <code>@solana/spl-token</code> library now offers API interfaces that assist in calculating the account length and the minimum rent requirement with extensions.</p><ul><li><p><code>getExtensionTypes</code>: Returns all the extensions supported by the mint.</p></li><li><p><code>getMinimumBalanceForRentExemptAccountWithExtensions</code>: Calculates the minimum rent needed for a token account with extensions.</p></li></ul><p>Here is an improved code snippet to mitigate the above issue.</p><pre><code>export const getCostToOpenTokenAccount = async (mint) =&gt; {
    const extensions = getExtensionTypes(mint.tlvData);
    const rent = await getMinimumBalanceForRentExemptAccountWithExtensions(
      connection,
      [...extensions]
    );
    const cost = rent * (10 ** mint.decimals);
    return cost;
}</code></pre><h3>1.2 Reallocation</h3><p>Some Account Extensions, such as Memo Transfer, can be added to a Token Account after its initial creation. Thus, the size of a Token Account may change dynamically. </p><p>To support the addition of new Account Extensions after the creation of Token Account, Token-2022 introduces a <code>Reallocate</code> IX that allows increasing the size of an existing Token Account to accommodate additional extension bytes.</p><blockquote><p>Within the Reallocate IX, if it is determined that the current Token Account size already meets the necessary requirements, the process will return without further reallocation.</p></blockquote><h4>Attention</h4><blockquote><p>When reallocating a Token Account to a larger size, additional rent will be charged according to the number of additional bytes. It is essential to consider who will cover this extra rent during the development process, as overlooking this aspect could lead to the protocol or project covering unexpected costs.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!U9zt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!U9zt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 424w, https://substackcdn.com/image/fetch/$s_!U9zt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 848w, https://substackcdn.com/image/fetch/$s_!U9zt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 1272w, https://substackcdn.com/image/fetch/$s_!U9zt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!U9zt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png" width="510" height="447.6510989010989" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1278,&quot;width&quot;:1456,&quot;resizeWidth&quot;:510,&quot;bytes&quot;:259839,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!U9zt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 424w, https://substackcdn.com/image/fetch/$s_!U9zt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 848w, https://substackcdn.com/image/fetch/$s_!U9zt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.png 1272w, https://substackcdn.com/image/fetch/$s_!U9zt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa2b8b8db-faad-40ba-895a-15d54d4967cb_1971x1730.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><blockquote><p>In particular, for the APIs that may be used, it is important to carefully consider how to set values for these parameters.</p><ul><li><p><code>payer</code> parameter in <a href="https://solana-labs.github.io/solana-program-library/token/js/functions/createReallocateInstruction.html">createReallocateInstruction</a></p></li><li><p><code>payer</code> parameter in <a href="https://docs.rs/spl-token-2022/4.0.1/src/spl_token_2022/instruction.rs.html#1848">reallocate</a></p></li></ul></blockquote><h3>1.3. Closing the Token Account</h3><p>A Token Account can be closed. </p><p>In SPL Token, a <code>non-WSOL</code> Token Account can be closed by the <code>account.authority</code> as long as <code>account.amount == 0</code> is satisfied.</p><p>However, in Token-2022, some additional conditions must be met to close a Token Account:</p><ul><li><p><code>account.amount == 0</code></p></li><li><p>If the close method is invoked in a CPI context and the Token Account has the <code>CPI Guard</code> extension enabled, the destination for the lamports must be the owner of Token Account.</p></li><li><p>If the Token Account supports the <code>Confidential Transfer</code> extension, both <code>pending_balance == 0</code> and <code>available_balance == 0</code> must be true.</p></li><li><p>If the Token Account supports the <code>Confidential Transfer Fee</code> extension, <code>withheld_amount == 0</code> must be ensured.</p></li><li><p>If the Token Account supports the <code>Transfer Fee</code> extension, <code>withheld_amount == 0</code> must be ensured.</p></li></ul><p>This is a simplified check flow in <a href="https://github.com/solana-labs/solana-program-library/blob/token-2022-v4.0.1/token/program-2022/src/processor.rs#L1134-L1181">SPL</a>:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Joz6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Joz6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 424w, https://substackcdn.com/image/fetch/$s_!Joz6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 848w, https://substackcdn.com/image/fetch/$s_!Joz6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 1272w, https://substackcdn.com/image/fetch/$s_!Joz6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Joz6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png" width="1456" height="314" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:314,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:335897,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Joz6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 424w, https://substackcdn.com/image/fetch/$s_!Joz6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 848w, https://substackcdn.com/image/fetch/$s_!Joz6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 1272w, https://substackcdn.com/image/fetch/$s_!Joz6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87d1fee6-75d0-4108-b268-2786b27d6606_5097x1098.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h4>Attention</h4><blockquote><p>If the contracts need to determine at runtime whether the criteria for closing a Token Account in Token-2022 are fulfilled, it is imperative that all the aforementioned conditions are satisfied. Otherwise, the Token Account cannot be closed directly.</p></blockquote><h4>Vulnerable Case</h4><p>In the following contract code snippet, an attempt is made to close Token Account A when its amount is 0. </p><pre><code>        if ctx.accounts.A.amount == 0 {
            close_account(CpiContext::new_with_signer(
                ctx.accounts.token_program.to_account_info(),
                CloseAccount {
                    account: ctx.accounts.A.to_account_info(),
                    destination: ctx.accounts.B.to_account_info(),
                    authority: ctx.accounts.B.to_account_info(),
                },
                signer_seeds,
            ))?;
        }</code></pre><p>If A is a Token Account of Token-2022 that supports Transfer Fee extensions, and <code>TransferFeeAmount.withheld_amount</code> is larger than 0, then it cannot be closed and an error will be raised in <code>close_account</code>: <code>AccountHasWithheldTransferFees: "An account can only be closed if its withheld fee balance is zero, harvest fees to the mint and try again"</code>. This error will cause the contract to fail to execute the IX because the condition <code>TransferFeeAmount.withheld_amount == 0</code> was not checked when verifying if A meets the closing requirements. </p><p>The <code>TransferFeeAmount</code> extension provides <code>closable</code> method to check this condition to avoid raising the error. Similarly, the other extensions also provide <code>closable</code> method for checking.</p><h4>Recommendation</h4><p>The following examples show how to close Token Accounts with various extensions and illustrate how to verify whether these extensions are closable.</p><h5>Cpi Guard</h5><pre><code>use solana_program::instruction::{get_stack_height, TRANSACTION_LEVEL_STACK_HEIGHT};
...
     if let Ok(cpi_guard) = source_account.get_extension::&lt;CpiGuard&gt;() {
         if cpi_guard.lock_cpi.into()
             &amp;&amp; get_stack_height() &gt; TRANSACTION_LEVEL_STACK_HEIGHT
             &amp;&amp; !cmp_pubkeys(destination_account_info.key, &amp;source_account.base.owner)
         {
             return Err(TokenError::CpiGuardCloseAccountBlocked.into());
         }
     }</code></pre><h5>Transfer Fee</h5><pre><code>   if let Ok(transfer_fee_state) = source_account.get_extension::&lt;TransferFeeAmount&gt;() {
       transfer_fee_state.closable()?
   }</code></pre><h5>Confidential Transfer</h5><pre><code>   if let Ok(confidential_transfer_state) =
       source_account.get_extension::&lt;ConfidentialTransferAccount&gt;()
   {
       confidential_transfer_state.closable()?
   }</code></pre><h5>Confidential Transfer Fee</h5><pre><code>   if let Ok(confidential_transfer_fee_state) =
       source_account.get_extension::&lt;ConfidentialTransferFeeAmount&gt;()
   {
       confidential_transfer_fee_state.closable()?
   }</code></pre><p> You can refer to the links below for detailed code implementations.</p><ul><li><p>Transfer Fee </p><ul><li><p>TransferFeeAmount: <a href="https://github.com/solana-labs/solana-program-library/blob/3522730070da7b7b6c19513b288c9faebd0be2ab/token/program-2022/src/extension/transfer_fee/mod.rs#L183">closable()</a></p></li></ul></li><li><p>Confidential Transfer</p><ul><li><p>ConfidentialTransferAccount: <a href="https://github.com/solana-labs/solana-program-library/blob/3522730070da7b7b6c19513b288c9faebd0be2ab/token/program-2022/src/extension/confidential_transfer/mod.rs#L136">closable()</a></p></li></ul></li><li><p>Confidential Transfer Fee</p><ul><li><p>ConfidentialTransferFeeAmount: <a href="https://github.com/solana-labs/solana-program-library/blob/3522730070da7b7b6c19513b288c9faebd0be2ab/token/program-2022/src/extension/confidential_transfer_fee/mod.rs#L70">closable()</a></p></li></ul></li></ul><h2>2. Mint Account</h2><p>Similar to Token Accounts, Token-2022 maintains the structure layout of the Mint Account and appends additional Extension Data fields. </p><p>Layout diagram is provided below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ui24!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ui24!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 424w, https://substackcdn.com/image/fetch/$s_!ui24!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 848w, https://substackcdn.com/image/fetch/$s_!ui24!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 1272w, https://substackcdn.com/image/fetch/$s_!ui24!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ui24!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png" width="166" height="342.4121863799283" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1151,&quot;width&quot;:558,&quot;resizeWidth&quot;:166,&quot;bytes&quot;:72009,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ui24!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 424w, https://substackcdn.com/image/fetch/$s_!ui24!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 848w, https://substackcdn.com/image/fetch/$s_!ui24!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.png 1272w, https://substackcdn.com/image/fetch/$s_!ui24!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffde6ab79-abec-4ab7-973c-78beee61c7df_558x1151.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 is a list with the extensions that could be appended to Mint Account&#65306;</p><ul><li><p>Non-Transferable Tokens</p></li><li><p>Transfer Fees</p></li><li><p>Transfer Hook</p></li><li><p>Confidential Transfer</p></li><li><p>Confidential Transfer Fee</p></li><li><p>Mint Close Authority</p></li><li><p>Default Account State</p></li><li><p>Interest-Bearing Tokens</p></li><li><p>Permanent Delegate</p></li><li><p>Metadata Pointer</p></li><li><p>Metadata</p></li><li><p>Group Pointer</p></li><li><p>Group</p></li><li><p>Group Member Pointer</p></li><li><p>Group Member</p></li></ul><p>Next, let's examine the security risks associated with the Mint Account at its creation and termination stages that developers should be aware of.</p><h3>2.1. Create Mint</h3><p>Different from Token Accounts, Token-2022 requires all extensions to be created before initializing the Mint Account. This is because most Mint Extensions are closely related to the Mint's tokenomics and core functionality. </p><p>Here is the list of Mint Extensions:</p><ul><li><p>confidential transfer</p></li><li><p>confidential transfer fee</p></li><li><p>default account state</p></li><li><p>group member pointer</p></li><li><p>group pointer</p></li><li><p>metadata pointer</p></li><li><p>interest-bearing mint</p></li><li><p>Transfer fee</p></li><li><p>Transfer hook</p></li><li><p>Immutable Owner</p></li><li><p>Mint Close Authority</p></li><li><p>Non Transferable</p></li><li><p>Permanent Delegate</p></li></ul><p>Furthermore, when initializing the Mint Account, <a href="https://github.com/solana-labs/solana-program-library/blob/token-2022-v4.0.1/token/program-2022/src/extension/mod.rs#L1292-L1321">additional checks</a> are required due to predefined constraints among Mint extensions. For example:</p><ul><li><p>If the <code>confidential transfer fee</code> is enabled, the <code>transfer fee</code> and <code>confidential transfer</code> must also be enabled.</p></li><li><p>If the <code>transfer fee</code> and <code>confidential transfer</code> are enabled, the <code>confidential transfer fee</code> must also be enabled.</p></li></ul><h4>Attention</h4><blockquote><p>Unlike Token Accounts, where extensions can be added after creation, all extensions for a Mint Account must be initialized before the Mint is created. Once a Mint Account is created, it is not possible to add new extensions.</p><p>This code snippet illustrates how to create a Mint with extensions.</p><pre><code>    // List extensions to be added to the new mint
    const extensions = [ExtensionType.TransferFeeConfig];

    // Calculate length of mint
    const mintLen = getMintLen(extensions);

    // Transfer Fee Config Parameters
    const decimals = 9;
    const feeBasisPoints = 50;
    const maxFee = BigInt(5_000);
    // Calculate minimum rent for create the new mint account
    const mintLamports = await connection.getMinimumBalanceForRentExemption(mintLen);

    // Mint Creation IXs
    // 1. Create a raw mint account with calculated mintLen and mintLamports
    // 2. Create TransferFee Config and append this extension to the mint account
    // 3. Initialize Mint 
    const mintTransaction = new Transaction().add(
        SystemProgram.createAccount({
            fromPubkey: payer.publicKey,
            newAccountPubkey: mint,
            space: mintLen,
            lamports: mintLamports,
            programId: TOKEN_2022_PROGRAM_ID,
        }),
        createInitializeTransferFeeConfigInstruction(
            mint,
            transferFeeConfigAuthority.publicKey,
            withdrawWithheldAuthority.publicKey,
            feeBasisPoints,
            maxFee,
            TOKEN_2022_PROGRAM_ID
        ),
        createInitializeMintInstruction(mint, decimals, mintAuthority.publicKey, null, TOKEN_2022_PROGRAM_ID)
    );
    await sendAndConfirmTransaction(connection, mintTransaction, [payer, mintKeypair], undefined);</code></pre></blockquote><h3>2.2. Close Mint</h3><p>In SPL Token, Mint accounts cannot be closed.</p><p>However, in Token-2022, it is possible to close a Mint by applying the <code>MintCloseAuthority</code> extension. </p><h4>Attention</h4><blockquote><p><code>MintCloseAuthority</code> requires that <code>Mint.supply == 0</code>.</p><p>When the Mint is <code>closable</code>, the amount of all token accounts related to this mint should be <strong>zero</strong> at that time.</p><p>However, if the Mint is closed and re-created with a different purpose at the same address. Inconsistencies will arise if your project stores information related to the Mint Account. If your project stores mint information, be aware of this potential issue and consider redesigning the code to ensure that it consistently fetches data from the correct mint.</p></blockquote><h2>3. Summary</h2><p>Some extensions in Token-2022 add data only to the Mint Account, some only to the Token Account, and others append data to both the Mint Account and the Token Account.</p><p>At the end of this section, we offer a brief summary that correlates these extensions with their respective accounts.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4_GB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4_GB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4_GB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4_GB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4_GB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4_GB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg" width="550" height="812" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:812,&quot;width&quot;:550,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:116587,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4_GB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 424w, https://substackcdn.com/image/fetch/$s_!4_GB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 848w, https://substackcdn.com/image/fetch/$s_!4_GB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!4_GB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20d2f82e-a955-4b63-8e68-2d10d1feab7c_550x812.jpeg 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><h1>Token Twins: Are You Using the Right One?</h1><p>Token-2022, being a proper superset of SPL Token, fully supports all 25 Token IXs with the same instruction layout and identical format. </p><p>In the following section, we outline several key differences between SPL Token and Token-2022 in the SPL.</p><h2>transfer VS transfer_checked</h2><p>In SPL Token, the <code>spl_token::instruction::transfer</code> method is used for mint transfer. However, in Token-2022, the <code>transfer</code> method has been <code>deprecated</code>.</p><pre><code>/// Creates a `Transfer` instruction.
#[deprecated(
    since = "4.0.0",
    note = "please use `transfer_checked` or `transfer_checked_with_fee` instead"
)]
pub fn transfer(</code></pre><p>The above code comments clearly indicate that it is recommended to use <code>transfer_checked</code> or <code>transfer_checked_with_fee</code>.</p><p>So, what issues might arise if you still uses the transfer method? </p><p>First, let&#8217;s review the definitions of the two suggested functions:</p><pre><code>/// Creates a `TransferChecked` instruction.
#[allow(clippy::too_many_arguments)]
pub fn transfer_checked(
    token_program_id: &amp;Pubkey,
    source_pubkey: &amp;Pubkey,
    mint_pubkey: &amp;Pubkey,
    destination_pubkey: &amp;Pubkey,
    authority_pubkey: &amp;Pubkey,
    signer_pubkeys: &amp;[&amp;Pubkey],
    amount: u64,
    decimals: u8,
) -&gt; Result&lt;Instruction, ProgramError&gt; {
...
}

/// Create a `TransferCheckedWithFee` instruction
#[allow(clippy::too_many_arguments)]
pub fn transfer_checked_with_fee(
    token_program_id: &amp;Pubkey,
    source: &amp;Pubkey,
    mint: &amp;Pubkey,
    destination: &amp;Pubkey,
    authority: &amp;Pubkey,
    signers: &amp;[&amp;Pubkey],
    amount: u64,
    decimals: u8,
    fee: u64,
) -&gt; Result&lt;Instruction, ProgramError&gt; {
    ...
}</code></pre><p>The changes could be found from diffs in <code>transfer vs transfer_checked</code>  and <code>transfer vs transfer_checked_with_fee</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gaA7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gaA7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 424w, https://substackcdn.com/image/fetch/$s_!gaA7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 848w, https://substackcdn.com/image/fetch/$s_!gaA7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 1272w, https://substackcdn.com/image/fetch/$s_!gaA7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gaA7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png" width="1456" height="354" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:354,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83282,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gaA7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 424w, https://substackcdn.com/image/fetch/$s_!gaA7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 848w, https://substackcdn.com/image/fetch/$s_!gaA7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 1272w, https://substackcdn.com/image/fetch/$s_!gaA7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecccbb32-94b1-4f79-a8be-fa0103f11f3b_1528x372.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nKH1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nKH1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 424w, https://substackcdn.com/image/fetch/$s_!nKH1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 848w, https://substackcdn.com/image/fetch/$s_!nKH1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 1272w, https://substackcdn.com/image/fetch/$s_!nKH1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nKH1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png" width="1456" height="398" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:398,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105796,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nKH1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 424w, https://substackcdn.com/image/fetch/$s_!nKH1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 848w, https://substackcdn.com/image/fetch/$s_!nKH1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.png 1272w, https://substackcdn.com/image/fetch/$s_!nKH1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8361b728-c6d1-40d2-9afa-41193902e3ee_1478x404.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>From the diff result, we have the following observations:</p><ul><li><p><code>transfer_checked</code> has 2 additional parameters compared to transfer: <code>mint_pubkey</code> and <code>decimals</code>.</p></li><li><p><code>transfer_checked_with_fee</code> has 3 additional parameters compared to <code>transfer</code>: <code>mint</code>, <code>decimals</code>, and <code>fee</code>.</p></li></ul><p>By reviewing the implementation of the transfer IX in Token-2022 program, it becomes clear that use of transfer may result in failure if the Token Account supports the <code>Transfer Hook</code> or <code>Transfer Fees</code> extensions, as these would prevent the transfer from being completed.</p><pre><code>    /// Processes a [Transfer](enum.TokenInstruction.html) instruction.
    pub fn process_transfer(
        program_id: &amp;Pubkey,
        accounts: &amp;[AccountInfo],
        amount: u64,
        expected_decimals: Option&lt;u8&gt;,
        expected_fee: Option&lt;u64&gt;,
    ) -&gt; ProgramResult {
        ...
        let expected_mint_info = if let Some(expected_decimals) = expected_decimals {
            Some((next_account_info(account_info_iter)?, expected_decimals))
        } else {
            None
        };
        ...
        let (fee, maybe_permanent_delegate, maybe_transfer_hook_program_id) =
            if let Some((mint_info, expected_decimals)) = expected_mint_info {
                ...
            } else {
                // Transfer hook extension exists on the account, but no mint
                // was provided to figure out required accounts, abort
                if source_account
                    .get_extension::&lt;TransferHookAccount&gt;()
                    .is_ok()
                {
                    return Err(TokenError::MintRequiredForTransfer.into());
                }
                // Transfer fee amount extension exists on the account, but no mint
                // was provided to calculate the fee, abort
                if source_account
                    .get_extension_mut::&lt;TransferFeeAmount&gt;()
                    .is_ok()
                {
                    return Err(TokenError::MintRequiredForTransfer.into());
                } else {
                    (0, None, None)
                }
            };
        ...</code></pre><p>The code shows that when the <code>transfer</code> function is invoked with <code>expected_decimals</code> set to <code>None</code>, it triggers the <code>else</code> branch in the code snippet. If the Token Account supports <code>Transfer Hook</code> or <code>Transfer Fees</code>, the <code>transfer</code> function will immediately return a <code>MintRequiredForTransfer</code> error and exit.</p><h4>Attention</h4><blockquote><p>It is recommended to stop using <code>transfer</code> in Token-2022 and use <code>transfer_checked</code> and <code>transfer_checked_with_fee</code> instead.</p><p>The full rust crate path for methods:</p><ul><li><p>transfer_checked:  <code>spl_token::instruction::transfer_checked</code></p></li><li><p>transfer_checked_with_fee: <code>spl_token_2022::extension::transfer_fee::instruction::transfer_checked_with_fee</code></p></li></ul></blockquote><h2>Two wSOLs</h2><p>In SPL Token, the account ID for WSOL is <code>So11111111111111111111111111111111111111112</code>. </p><p>Token-2022 has introduced a new WSOL with the account ID <code>9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP</code>.</p><h4>Attention</h4><blockquote><p>If your contract needs to special handling WSOL, it is important to distinguish WSOL between SPL Token and Token-2022.</p><p>As of September 2024, the WSOL in Token-2022 has very little trading activity, so WSOL usually refers to the SPL Token's <code>So11111111111111111111111111111111111111112</code>.</p><p>For some DeFi platforms, where SOL/WSOL assets carry specific importance, it is advisable to blacklist the Token-2022 WSOL address to avoid any potential ambiguity.</p></blockquote><h2>The Different Program ID</h2><p>SPL Token Program and Token-2022 Program are separate programs, each with a different Program ID.</p><ul><li><p>SPL Token Program ID: <code>TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA</code></p></li><li><p>Token-2022 Program ID: <code>TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb</code></p></li></ul><h4>Attention</h4><blockquote><p>In some Solana SDK interfaces, if the corresponding instructions work for both SPL Token and Token-2022, the SPL Token program is typically used as the default program ID parameter.<br>For example, here's the declaration of the <code>createAssociatedTokenAccountInstruction</code> function in the <code>solana/@spl_token</code> SDK:</p><pre><code>export function createAssociatedTokenAccountInstruction(
    payer: PublicKey,
    associatedToken: PublicKey,
    owner: PublicKey,
    mint: PublicKey,
    programId = TOKEN_PROGRAM_ID,       // &lt;---- SPL Token Program ID
    associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
)</code></pre><p>When using these SDK interfaces, developers should <code>clearly identify which Token program they need to call</code>.</p></blockquote><h1>How to Integrate Token-2022 into an Anchor Project?</h1><p><a href="https://www.anchor-lang.com/">Anchor</a>, the most popular development framework on Solana, supports Token-2022 by providing various types and IX wrappers. Developers could utilize these types and methods provided by Anchor. </p><h2>Types</h2><p>Here is a summary of the type definitions and the SPL Token Program types they support:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v9yI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v9yI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 424w, https://substackcdn.com/image/fetch/$s_!v9yI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 848w, https://substackcdn.com/image/fetch/$s_!v9yI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!v9yI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v9yI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg" width="731" height="429" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:429,&quot;width&quot;:731,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:66374,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v9yI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 424w, https://substackcdn.com/image/fetch/$s_!v9yI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 848w, https://substackcdn.com/image/fetch/$s_!v9yI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!v9yI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5113f903-c2cc-4669-b525-1198ee62bd26_731x429.jpeg 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>We have some observations from the table:</p><ul><li><p>Types under the <code>token_interface</code> path are compatible with both the SPL Token Program and the Token-2022 Program.</p></li><li><p>Types under the <code>token</code> path are only compatible with the SPL Token Program.</p></li><li><p>Types under the <code>token_2022</code> path are exclusively for the Token-2022 Program.</p></li></ul><h4>Attention</h4><blockquote><p>When developing, it is crucial to decide whether the contract needs to support Token-2022.</p><ul><li><p>If Token-2022 support is <code>required</code>, it is recommended to use the types under <code>anchor_spl::token_interface</code>.</p></li><li><p>If Token-2022 support is <code>not needed</code>, it is recommended to use the types under <code>anchor_spl::token::Token</code>.</p></li></ul><p>If your contract does not intend to support Token-2022 but uses types from the <code>anchor_spl::token_interface</code> path, it could lead to unexpected issues due to ambiguity. </p></blockquote><h1>Conclusion</h1><p>This is our first article on Token-2022 series, based on our experiences from dozens of Token-2022-related audits. The article highlights potential security risks in Token-2022 accounts during development. Developers should be cautious, as improper design or implementation can lead to significant threats to project security.</p><p>In the next article, we will dive deeper into <code>Extensions</code> in Token-2022 that could affect the security of funds for both projects and users. Stay tuned for more insights.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Stop Spoofing My Wallet!]]></title><description><![CDATA[Demystifying Simulation Spoofing Attacks]]></description><link>https://blog.offside.io/p/stop-spoofing-my-wallet</link><guid isPermaLink="false">https://blog.offside.io/p/stop-spoofing-my-wallet</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Wed, 04 Sep 2024 09:32:39 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/02e7b7e8-5f9b-45fc-8afa-5317b640ce3b_1600x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>Recently, there&#8217;s been a surge in <a href="https://x.com/JupiterExchange/status/1825600323320434830">sophisticated</a> <a href="https://x.com/PocketUniverseZ/status/1825655345739350352">phishing</a> <a href="https://x.com/0xslipper/status/1825778730356167031">attacks</a> targeting <a href="https://solana.com">Solana</a> users, bypassing even the most secure wallet protections. While users authorize transactions with a simple click, they may unknowingly approve malicious activities.</p><p>These attacks exploit the hidden complexities of wallet interactions, putting funds at risk. We&#8217;ll reveal how these attacks work, share real-life cases, and provide tips to help you stay safe.</p></blockquote><h2>The Hidden Dangers of Wallet Interactions</h2><p>Imagine a scenario where your wallet shows you&#8217;re about to make a swap on <a href="https://jup.ag/">Jupiter</a>, but in reality, you&#8217;re unknowingly authorizing a malicious transaction that could drain your entire account. This isn&#8217;t just a hypothetical situation &#8211; it&#8217;s a growing threat in the Solana ecosystem.</p><p>Every day, countless users interact with their Solana wallets, authorizing transactions with a simple click. But what really happens behind the scenes once you hit that &#8220;Sign&#8221; button? The truth is, there&#8217;s much more going on than meets the eye.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5V6M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5V6M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 424w, https://substackcdn.com/image/fetch/$s_!5V6M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 848w, https://substackcdn.com/image/fetch/$s_!5V6M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 1272w, https://substackcdn.com/image/fetch/$s_!5V6M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5V6M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png" width="1456" height="813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!5V6M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 424w, https://substackcdn.com/image/fetch/$s_!5V6M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 848w, https://substackcdn.com/image/fetch/$s_!5V6M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 1272w, https://substackcdn.com/image/fetch/$s_!5V6M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F75837a3e-598b-4a9b-a376-fe5baa845cb2_2248x1255.png 1456w" sizes="100vw" fetchpriority="high"></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>In recent weeks, the community has witnessed a disturbing trend: sophisticated phishing attacks targeting Solana users that bypass even the most robust wallet security measures. As we delve deeper, we'll uncover the &#8220;black magic&#8221; behind these attacks, explore real-world cases, and arm you with the knowledge to protect yourself.</p><h2>Drainer Alert: A Series of Sophisticated Attacks</h2><p>The alarm bells started ringing a few weeks ago when the Jupiter Team forwarded reports of suspicious hacking incidents from multiple victims. With no clear indication of the root cause and new victims coming every few hours, we found ourselves in a race against time to uncover the grifter's hiding place before more users got drained.</p><p>A pattern quickly emerged among the victims: they were Solana users using the <a href="https://phantom.app">Phantom</a> wallet via a Chrome extension on Windows. These attacks weren&#8217;t limited to a specific DeFi protocol but were identified on various platforms, including Jupiter products and <a href="https://raydium.io">Raydium</a>.<br>From these incidents, we could draw a few important conclusions:</p><ul><li><p>The attack method was not widespread, as the number of victims was not explosively increasing.</p></li><li><p>These attacks were not targeting specific users, because the victims appeared to be random and not exclusively &#8220;whales&#8221;.</p></li><li><p>The vulnerability didn&#8217;t seem to be tied to a specific DeFi product but appeared to be related to the Phantom browser extension wallet.</p></li><li><p>The attacker had no direct control of the victim&#8217;s wallet or private keys because the attacks were only triggered by user interactions.</p></li></ul><p>As we delve deeper into this mystery, we invite you, our fellow sleuths, to join us in tracing the root causes. What theories or ideas come to your mind, Sheriff Cat?</p><h2>Solana Transactions Basics</h2><h3>Unpacking a Solana Transaction</h3><p>To comprehend the sophistication of these attacks, we first need to understand the structure and workflow of a typical Solana transaction. A Solana transaction is a compact but powerful data structure that encapsulates all the information needed to execute a set of actions on the blockchain. Let&#8217;s break down its components:</p><ul><li><p>Signatures: A list of signatures, one for each signer required by the transaction. These signatures cryptographically prove that the signers authorize the transaction.</p></li><li><p>Message: The core content of the transaction, containing:</p><ul><li><p>Header: Includes metadata such as the number of required signatures and the number of read-only account references.</p></li><li><p>Account Addresses: A list of all accounts that will be read from or written to during transaction execution.</p></li><li><p>Recent Blockhash: A recent blockhash to prevent transaction replay and ensure freshness.</p></li><li><p>Instructions: The actual commands to be executed. Each instruction within the transaction message contains the following:</p><ul><li><p>Program ID: The address of the program that will process this instruction.</p></li><li><p>Accounts: A list of accounts involved in this specific instruction.</p></li><li><p>Instruction Data: Arbitrary byte array interpreted by the program.</p></li></ul></li></ul></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_!VNcB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VNcB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 424w, https://substackcdn.com/image/fetch/$s_!VNcB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 848w, https://substackcdn.com/image/fetch/$s_!VNcB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!VNcB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VNcB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg" width="800" height="456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:456,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Anatomy of a Solana transaction&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Anatomy of a Solana transaction" title="Anatomy of a Solana transaction" srcset="https://substackcdn.com/image/fetch/$s_!VNcB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 424w, https://substackcdn.com/image/fetch/$s_!VNcB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 848w, https://substackcdn.com/image/fetch/$s_!VNcB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!VNcB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f337719-611e-41c7-9239-f500de570cc8_800x456.jpeg 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><figcaption class="image-caption"><a href="https://blog.labeleven.dev/anatomy-of-solana-program-invocations-using-anchor">Anatomy of Solana Program Invocations</a></figcaption></figure></div><h3>The Lifecycle of a Token Swap</h3><p>Let&#8217;s take a common scenario like token swapping on Jupiter as an example. When you initiate a swap on Jupiter, several steps occur behind the scenes. First, Jupiter fetches the current token price for your reference. It then queries its backend to determine the most efficient routing for your swap. With this information, the front end assembles the routing details into a series of instructions that will form the transaction.</p><p>Once the instructions are assembled, an unsigned transaction is created and submitted to your connected wallet. At this point, your wallet plays a crucial role in security. It typically queries a backend service for simulation results (more details covered in the next section), allowing it to predict the outcome of the transaction. Based on these results, the wallet prompts you, the user, for confirmation. If you approve, the wallet signs the transaction and submits it to an RPC client, which then broadcasts it to the Solana network for confirmation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BP_l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BP_l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 424w, https://substackcdn.com/image/fetch/$s_!BP_l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 848w, https://substackcdn.com/image/fetch/$s_!BP_l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 1272w, https://substackcdn.com/image/fetch/$s_!BP_l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BP_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png" width="800" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:619063,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BP_l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 424w, https://substackcdn.com/image/fetch/$s_!BP_l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 848w, https://substackcdn.com/image/fetch/$s_!BP_l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.png 1272w, https://substackcdn.com/image/fetch/$s_!BP_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e8d013-a372-4974-88f1-faef8e2b7d3e_800x600.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><h3>&#8220;Unlimited Approval&#8221; as a Signer</h3><p>On Solana, signing a transaction grants full authority over your account for that transaction&#8217;s scope. This is similar to &#8220;unlimited approval&#8221; in Ethereum, but with a key difference: it happens automatically with every signature.</p><p>When you sign, you authorize the transaction to act on your behalf for all included accounts. This means a single signature can permit multiple actions, including unexpected token transfers, without additional prompts. In the context of a malicious attack, this could allow a bad actor to include harmful instructions that appear legitimate to the user!</p><h3>Case Study &#8211; Anatomy of a Malicious Transaction</h3><p>To illustrate this, let's examine a malicious transaction we encountered during our investigation. Transaction <a href="https://solscan.io/tx/5krgaq2FTZAp9CT1X1ue4dY7JV2rSVYeNLQFgHjWKFcyTE88wU54KWKhvuzcG4Fm6bfdByk1ngiyewcjLydWc93d">5krgaq2FTZAp9CT1X1ue4dY7JV2rSVYeNLQFgHjWKFcyTE88wU54KWKhvuzcG4Fm6bfdByk1ngiyewcjLydWc93d</a> appeared to be a standard token swap on the surface.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!y9pf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!y9pf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 424w, https://substackcdn.com/image/fetch/$s_!y9pf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 848w, https://substackcdn.com/image/fetch/$s_!y9pf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 1272w, https://substackcdn.com/image/fetch/$s_!y9pf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!y9pf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png" width="936" height="412" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:412,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!y9pf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 424w, https://substackcdn.com/image/fetch/$s_!y9pf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 848w, https://substackcdn.com/image/fetch/$s_!y9pf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.png 1272w, https://substackcdn.com/image/fetch/$s_!y9pf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a064c78-10cc-4cc9-a154-2864b962a33d_936x412.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>However, upon closer inspection, we discovered additional instructions embedded within the transaction. </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0WCC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0WCC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 424w, https://substackcdn.com/image/fetch/$s_!0WCC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 848w, https://substackcdn.com/image/fetch/$s_!0WCC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 1272w, https://substackcdn.com/image/fetch/$s_!0WCC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0WCC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png" width="936" height="168" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85b63676-6657-4967-975e-61b41b0a18d8_936x168.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:168,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!0WCC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 424w, https://substackcdn.com/image/fetch/$s_!0WCC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 848w, https://substackcdn.com/image/fetch/$s_!0WCC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 1272w, https://substackcdn.com/image/fetch/$s_!0WCC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85b63676-6657-4967-975e-61b41b0a18d8_936x168.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>These malicious instructions were made to steal funds and take control of the victim&#8217;s token account while pretending to be part of the normal swap process.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9rES!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9rES!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 424w, https://substackcdn.com/image/fetch/$s_!9rES!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 848w, https://substackcdn.com/image/fetch/$s_!9rES!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 1272w, https://substackcdn.com/image/fetch/$s_!9rES!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9rES!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png" width="936" height="840" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:840,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!9rES!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 424w, https://substackcdn.com/image/fetch/$s_!9rES!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 848w, https://substackcdn.com/image/fetch/$s_!9rES!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.png 1272w, https://substackcdn.com/image/fetch/$s_!9rES!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e004580-5e50-4a4a-9864-6072a7ab5f9d_936x840.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><h2>Default Safeguard: Transaction Simulation</h2><p>Modern wallets like Phantom usually utilize embedded analyzers to provide users with comprehensive information before signing. Transaction simulation is a critical feature that allows the wallet to predict transaction outcomes before execution.</p><p>Phantom Wallet employs this measure in partnership with <a href="https://blowfish.xyz/">Blowfish</a>, a specialized analysis provider, as stated in their <a href="https://phantom.app/learn/blog/auto-confirm">blog</a>:</p><blockquote><p><strong>Secure transaction scanning</strong><br>We scan transactions and messages with Blowfish. If we find anything fishy, we warn you via a pop-up alert so you can take a closer look, and if necessary, avoid the transaction altogether. If we can&#8217;t simulate it, we&#8217;ll return you to the normal confirmation flow. If something is wrong, we break out of Auto-Confirm and alert you.</p></blockquote><p>When a user initiates a transaction in Phantom, the unsigned transaction is sent to Blowfish&#8217;s servers for simulation in a controlled environment. This process can identify various threats, including unexpected token transfers, interactions with suspicious smart contracts, potential rug pulls, and abnormal slippage in DEX transactions.</p><p>However, simulation has limitations. As we&#8217;ll see in our case study, sophisticated attacks can still bypass these checks through clever programming and exploitation of simulation constraints.</p><h3>Case Study &#8211; Examining a Simulation Log</h3><p>We were quite confused as to why the built-in transaction simulation did not protect the victims. Luckily, a sample of a victim&#8217;s simulation provided by Blowfish confirmed our guess: the simulation failed to reveal the malicious behaviors.</p><p>In the log, the malicious program did not execute long or consume many compute units:</p><pre><code>&#8220;Program  5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr invoke [1]&#8221;,
&#8220;Program  5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr consumed 1106 of 102657 compute  units&#8221;,
&#8220;Program  5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr success&#8221;</code></pre><p>However, the on-chain log shows different traces: </p><pre><code>Program  5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr invoke [1]
Program  11111111111111111111111111111111 invoke [2]
Program  11111111111111111111111111111111 success
Program  TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]
Program log: Instruction:  SetAuthority
Program  TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2875 of 97266 compute  units
Program  TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success
Program  5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr consumed 8480 of 102668 compute  units
Program  5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr success</code></pre><p>So, what happened in this program <a href="https://solscan.io/account/5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr">5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr</a>?</p><h2>Unmasking the Malware: Reverse Engineering</h2><h3>Executable Program Accounts on Solana</h3><p>On Solana, smart contracts are deployed as executable program accounts. These accounts store the compiled bytecode of the program, which can be executed by the Solana runtime. Unlike Ethereum&#8217;s EVM bytecode, Solana programs are compiled to BPF bytecode, which is a nightmare for reverse engineering.</p><p>Our target program is 5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr. The program content could be dumped via Solana&#8217;s built-in command:</p><pre><code>$ solana program dump 5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr a.elf -u https://api.mainnet-beta.solana.com
Wrote program to a.elf

$ file a.elf
a.elf: ELF 64-bit LSB shared object, eBPF, version 1 (SYSV), dynamically linked, stripped</code></pre><p>Now we have an ELF file containing BPF bytecode.</p><h3>Reverse Engineering like an OtterSec Pro</h3><p>Reverse engineering a program in a nontraditional instruction set is never a trivial task. Luckily, we could stand on the shoulders of pioneers: OtterSec has open-sourced their <a href="https://github.com/otter-sec/bn-ebpf-solana">amazing eBPF decompiler plugin</a> for reverse engineering!</p><p>The decompiled pseudo c code is like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IqUD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IqUD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 424w, https://substackcdn.com/image/fetch/$s_!IqUD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 848w, https://substackcdn.com/image/fetch/$s_!IqUD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 1272w, https://substackcdn.com/image/fetch/$s_!IqUD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IqUD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png" width="1003" height="803" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:803,&quot;width&quot;:1003,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:161982,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IqUD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 424w, https://substackcdn.com/image/fetch/$s_!IqUD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 848w, https://substackcdn.com/image/fetch/$s_!IqUD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.png 1272w, https://substackcdn.com/image/fetch/$s_!IqUD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb768a88-2dc7-4d42-be76-0b48bdb6868c_1003x803.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>As we mentioned earlier, the program in simulation consumed much fewer computing units. We suspected an early exit was triggered somewhere and we found these suspicious constant comparisons and &#8220;goto label_100000718&#8221; jumps, as shown above.</p><p>A deeper analysis reveals that variable <code>r7 </code>here points to the array of input accounts, with each size being 0x30 bytes. Thus <code>r7 + 0x30</code> is account #2, <code>r7 + 0x60</code> is account #3. Dereferencing the first pointer in an account is reading its <code>key</code>.</p><p>The four magic numbers <code>0x4d702b828d0f0a6e</code>, <code>0x2a8e185ab7b764da</code>, <code>0x7752c6d53f4d424b</code>, and <code>0xef7a7aa1ace0d9</code>, make up a 256-bit big number <code>0x6e0a0f8d822b704dda64b7b75a188e2a4b424d3fd5c65277d9e0aca17a7aef00</code>, which is exactly the raw representation of account <code>8QYkBcer7kzCtXJGNazCR6jrRJS829aBow12jUob3jhR</code>!</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-mko!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-mko!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 424w, https://substackcdn.com/image/fetch/$s_!-mko!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 848w, https://substackcdn.com/image/fetch/$s_!-mko!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 1272w, https://substackcdn.com/image/fetch/$s_!-mko!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-mko!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png" width="936" height="234" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:234,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!-mko!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 424w, https://substackcdn.com/image/fetch/$s_!-mko!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 848w, https://substackcdn.com/image/fetch/$s_!-mko!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 1272w, https://substackcdn.com/image/fetch/$s_!-mko!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0be5fd3-df6a-4d09-b38c-dfec4a68aaab_936x234.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The program rejects any invocation with mismatching account #2. But what makes its on-chain behavior deviate from the simulation? Let&#8217;s take a deeper look at the last &#8220;goto&#8221; jump.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8fDb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8fDb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 424w, https://substackcdn.com/image/fetch/$s_!8fDb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 848w, https://substackcdn.com/image/fetch/$s_!8fDb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 1272w, https://substackcdn.com/image/fetch/$s_!8fDb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8fDb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png" width="846" height="355" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:355,&quot;width&quot;:846,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:123786,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8fDb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 424w, https://substackcdn.com/image/fetch/$s_!8fDb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 848w, https://substackcdn.com/image/fetch/$s_!8fDb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.png 1272w, https://substackcdn.com/image/fetch/$s_!8fDb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f6f69ff-255a-46f5-81d5-e418c184e632_846x355.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>Function <code>sub_100003120(account #3)</code> just dereferences and loads the lamports field of account #3. If it&#8217;s zero, the program silently exits. (Check the definition of <code>AccountInfo</code> struct <a href="https://github.com/anza-xyz/agave/blob/fff6257b0d0ed2c929fb31c20413314b0a2f0b96/sdk/program/src/account_info.rs#L17-L37">here</a>)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gPun!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gPun!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 424w, https://substackcdn.com/image/fetch/$s_!gPun!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 848w, https://substackcdn.com/image/fetch/$s_!gPun!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 1272w, https://substackcdn.com/image/fetch/$s_!gPun!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gPun!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png" width="936" height="332" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:332,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!gPun!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 424w, https://substackcdn.com/image/fetch/$s_!gPun!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 848w, https://substackcdn.com/image/fetch/$s_!gPun!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.png 1272w, https://substackcdn.com/image/fetch/$s_!gPun!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F241fb05f-8ebc-4dc8-a3a6-6c89142cabdc_936x332.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>Thus the balance (lamports) of the third input account, is the key to the backdoor!<br>Checking the corresponding account <a href="https://solscan.io/account/BKW62NtBeQJkjbBdh61WNfpfuT6ai34pU1eX4QPjxQyW">BKW62NtBeQJkjbBdh61WNfpfuT6ai34pU1eX4QPjxQyW</a> in our case, only three consecutive transactions are recorded.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0pE9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0pE9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 424w, https://substackcdn.com/image/fetch/$s_!0pE9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 848w, https://substackcdn.com/image/fetch/$s_!0pE9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 1272w, https://substackcdn.com/image/fetch/$s_!0pE9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0pE9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png" width="936" height="200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:200,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!0pE9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 424w, https://substackcdn.com/image/fetch/$s_!0pE9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 848w, https://substackcdn.com/image/fetch/$s_!0pE9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 1272w, https://substackcdn.com/image/fetch/$s_!0pE9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2599ec1e-9f8f-4596-bf00-46e4ef4193e4_936x200.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The <a href="https://solscan.io/tx/424fD81zbhrG2pBopeknip4QAYjbz9YMFZA5gnxvd28Q4DbJV3h2krHoeCxnvWzDHw3CuxH9tkWQFppiXFFSrjCi">first transaction</a> (last in the picture) deposited SOL into account BKW6. The <a href="https://solscan.io/tx/Mi6HxScSZX2PZDPX7P5WaMncuRojTX6YhDjpbToi2b9ssG2DBuaPH2vwpCtZDGGnB841UJkL7wJenjzk1aY4edi">final transaction</a> zeroed account BKW6 and tipped Jito. The malicious transaction was &#8220;sandwiched&#8221; by the others, just like quickly turning the switch on and off. In this way, the malicious behavior can only be triggered in a very narrow time window, never in the simulation, nor even after the execution.</p><h2>Crime Scene Investigation</h2><h3>The Suspected Extension: Bull Checker</h3><p>Upon further investigation of several affected users who have been drained by the same program, we have identified an extension called &#8220;Bull Checker&#8221;, which has the permission to read and change all the data on the website, as a potential cause.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ffCS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ffCS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 424w, https://substackcdn.com/image/fetch/$s_!ffCS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 848w, https://substackcdn.com/image/fetch/$s_!ffCS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 1272w, https://substackcdn.com/image/fetch/$s_!ffCS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ffCS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png" width="936" height="392" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:392,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!ffCS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 424w, https://substackcdn.com/image/fetch/$s_!ffCS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 848w, https://substackcdn.com/image/fetch/$s_!ffCS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.png 1272w, https://substackcdn.com/image/fetch/$s_!ffCS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e1f3099-d24c-48b2-8942-860df7f1d085_936x392.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>Bull Checker is supposed to be a read-only extension that allows you to view the holders of memecoins. There should be no need for an extension like this to read or write data on all websites.</p><p>This should have been a major red flag for users, but apparently, several users continued to install and use the extension.</p><h3>Targeting Memecoin Traders</h3><p>In addition to the above information, while researching &#8220;Bull Checker&#8221; we discovered that it was <a href="https://www.reddit.com/r/solana/comments/1eq24yc/comment/lhq1exn/">publicized</a> by an anonymous Reddit account, &#8220;Solana_OG&#8221; (now deleted). This person appeared to target <a href="https://www.reddit.com/r/solana/comments/1emepbg/comment/lgyc8f9/">users looking to trade memecoins</a> and lured them to download the extension.</p><h3>Spoofing Workflow Revealed</h3><p>The extension has now been removed from the Chrome Web Store. We can find the cached stats <a href="https://chrome-stats.com/d/cbkmnkpemfkgdlnjiicinflikkgcphie">here</a>. The bundled files can be extracted by unzipping the extension as a zip file. These files are compressed but not heavily obfuscated and can be recovered using JavaScript beautifier tools.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K9Ue!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K9Ue!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 424w, https://substackcdn.com/image/fetch/$s_!K9Ue!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 848w, https://substackcdn.com/image/fetch/$s_!K9Ue!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 1272w, https://substackcdn.com/image/fetch/$s_!K9Ue!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K9Ue!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png" width="704" height="736" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:736,&quot;width&quot;:704,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!K9Ue!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 424w, https://substackcdn.com/image/fetch/$s_!K9Ue!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 848w, https://substackcdn.com/image/fetch/$s_!K9Ue!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.png 1272w, https://substackcdn.com/image/fetch/$s_!K9Ue!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F791f3634-c496-4513-bc01-2b58dc20dd0d_704x736.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>The prettified `pha.292c2974.js` contains suspicious code related to the Phantom wallet. Since it can read and change data on all websites, it actively monitors apps containing the wallet adapter.</p><p>It replaces the wallet adapter&#8217;s <code>signTransaction</code> method with its own implementation. If it detects a &#8220;simple&#8221; transaction with only one signer, it forwards this unsigned message to a remote server through an encrypted channel. On the server side, it determines the token accounts owned by the victim to take over, generates a fresh &#8220;switch&#8221; account for the victim, and then appends the drainer instruction to the original unsigned transaction.</p><p>The modified transaction is then submitted to Phantom for user confirmation. Once approved, the signed transaction is immediately sent to the server again. The server broadcasts the &#8220;sandwiched" transaction in <a href="https://explorer.jito.wtf/bundle/a499e2f693fc02377a09558ffbc7a0cf5d2997c36380c792e08673cf79a15e1a">a Jito bundle</a> to ensure the drainer in the backdoor is exactly triggered on-chain.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XcRp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XcRp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 424w, https://substackcdn.com/image/fetch/$s_!XcRp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 848w, https://substackcdn.com/image/fetch/$s_!XcRp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 1272w, https://substackcdn.com/image/fetch/$s_!XcRp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XcRp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png" width="1456" height="692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:692,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:314306,&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;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XcRp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 424w, https://substackcdn.com/image/fetch/$s_!XcRp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 848w, https://substackcdn.com/image/fetch/$s_!XcRp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.png 1272w, https://substackcdn.com/image/fetch/$s_!XcRp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F859ab70b-7fe0-4194-9198-22cb68922d80_2252x1071.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><h2>Stop Spoofing and Stay Safe</h2><p>Through collaborative efforts with Jupiter, Blowfish, Raydium, Phantom, and Offside Labs, we have uncovered the root cause of this series of crypto thefts. The Bull Checker extension has been removed, and the associated program account has been <a href="https://solscan.io/account/5UMucMksJweA1AtgyxrK8DJeBXr3DQGEGRs5Kkq2pZjr">labeled</a> as malicious.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e-ez!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e-ez!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 424w, https://substackcdn.com/image/fetch/$s_!e-ez!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 848w, https://substackcdn.com/image/fetch/$s_!e-ez!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 1272w, https://substackcdn.com/image/fetch/$s_!e-ez!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e-ez!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png" width="936" height="82" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:82,&quot;width&quot;:936,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;image.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="image.png" title="image.png" srcset="https://substackcdn.com/image/fetch/$s_!e-ez!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 424w, https://substackcdn.com/image/fetch/$s_!e-ez!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 848w, https://substackcdn.com/image/fetch/$s_!e-ez!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 1272w, https://substackcdn.com/image/fetch/$s_!e-ez!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe90a222-2f9b-448f-93c9-f9d0461e3086_936x82.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>While we have identified one malicious extension, there might still be other malicious extensions out there. There have been reports of other drains that we have not been able to track down. It&#8217;s crucial to maintain a healthy skepticism, even towards seemingly popular recommendations on social media platforms. Do not trust something just because someone mentioned it on Reddit or other media and it has many upvotes. Stay away from those &#8220;Solana OG&#8221;. Astroturfing and social engineering are very real.</p><p>Extensions that request extensive permissions are highly suspicious. An extension like Bull Checker should not need to read and modify all your website data. You should have an extremely high degree of confidence in an extension before you start using it.</p><p>Fortunately, there are ways to mitigate similar spoofing issues in the future. Unlike Ethereum, Solana transactions predeclare all accessed accounts in the message header before signing. This feature allows wallets and simulation-based analyzers to detect unusual patterns or unknown program invocations, potentially raising alarms regardless of whether the execution triggers malicious behavior.</p><p>In addition, Blowfish has released a new guard instruction feature called SafeGuard that prevents all simulation spoofing attacks. It&#8217;s currently being adopted by multiple Solana wallets and will prevent future such attacks.</p><h2>Conclusion</h2><p>This investigation has been an insightful journey, made possible through close collaboration with the Jupiter team. We extend our sincere gratitude to the teams at Blowfish, Raydium, and Phantom for their invaluable assistance throughout this process.</p><p>It's been a privilege to work alongside these dedicated teams, all of whom share a common mission: prioritizing the security of every user in the web3 ecosystem. This commitment aligns perfectly with our core values at Offside Labs.</p><p>As we conclude this investigation, we urge all users to remain vigilant in the face of evolving threats. The crypto landscape is dynamic, and new challenges will undoubtedly emerge. Remember to always verify, question, and stay informed. Keep watching for updates from Offside Labs as we continue our mission to enhance blockchain security.</p><p>Stay safe, stay curious, and keep an eye out for the Offside!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Compensation for Composition]]></title><description><![CDATA[In this blog post, we reveal an issue in the Trader Joe v2 Liquidity Book. This flaw lets arbitragers perform swaps without paying fees, allowing them to reclaim a portion of the fees meant for existing liquidity providers.]]></description><link>https://blog.offside.io/p/compensation-for-composition</link><guid isPermaLink="false">https://blog.offside.io/p/compensation-for-composition</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Fri, 02 Aug 2024 12:31:05 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pCxI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pCxI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 424w, https://substackcdn.com/image/fetch/$s_!pCxI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 848w, https://substackcdn.com/image/fetch/$s_!pCxI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 1272w, https://substackcdn.com/image/fetch/$s_!pCxI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pCxI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png" width="1024" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1541468,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pCxI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 424w, https://substackcdn.com/image/fetch/$s_!pCxI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 848w, https://substackcdn.com/image/fetch/$s_!pCxI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 1272w, https://substackcdn.com/image/fetch/$s_!pCxI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21dd4a4e-719a-4133-925b-c00b3c39fc6e_1024x768.png 1456w" sizes="100vw" fetchpriority="high"></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><blockquote><p>In this blog post, we reveal an issue in the <em><strong>Trader Joe v2 Liquidity Book</strong></em>. This flaw lets arbitragers perform swaps without paying fees, allowing them to reclaim a portion of the fees meant for existing liquidity providers. As a result, arbitragers can swap tokens without any cost.</p></blockquote><h2>Who&#8217;s Trader Joe?</h2><p>To understand the flaw, let's first introduce the core concepts of <em>Trader Joe v2</em>. <em><strong>Trader Joe v2 Liquidity Book</strong></em> (LB) is a decentralized exchange that offers concentrated liquidity. It uses the <strong>Constant Sum Market Maker Function</strong>, which means liquidity is stacked vertically across different <em>bin arrays</em>. This setup aims to improve trading efficiency and maximize rewards for liquidity providers.</p><p>In <em>JOE LB</em>, token X is called the <strong>Base Asset,</strong> and token Y is called the <strong>Quote Asset</strong>. Price <strong>P</strong> is defined as the amount of the quote token you supply (<strong>&#916;y)</strong> compared to the amount of the base token (<strong>&#916;x)</strong> you can get.</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;P=\\frac{\\Delta y}{\\Delta x}&quot;,&quot;id&quot;:&quot;LFMIXWCWXL&quot;}" data-component-name="LatexBlockToDOM"></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v68L!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v68L!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 424w, https://substackcdn.com/image/fetch/$s_!v68L!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 848w, https://substackcdn.com/image/fetch/$s_!v68L!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 1272w, https://substackcdn.com/image/fetch/$s_!v68L!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v68L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png" width="524" height="541" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6622de00-c022-4c90-a4ce-833971b9a867_524x541.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:541,&quot;width&quot;:524,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:28436,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v68L!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 424w, https://substackcdn.com/image/fetch/$s_!v68L!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 848w, https://substackcdn.com/image/fetch/$s_!v68L!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 1272w, https://substackcdn.com/image/fetch/$s_!v68L!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6622de00-c022-4c90-a4ce-833971b9a867_524x541.png 1456w" sizes="100vw"></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>Since the price of each individual bin <strong>Pi</strong> is the same, the liquidity of each bin is defined as </p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;L = P_i \\times x + y&quot;,&quot;id&quot;:&quot;ROPJIYIVNL&quot;}" data-component-name="LatexBlockToDOM"></div><p><strong>Bin Composition (c)</strong>, or composition factor/ratio, denotes the ratio of the remaining quote token in the <em><strong>current active bin</strong></em>. </p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;c=\\frac{y}{L}&quot;,&quot;id&quot;:&quot;VDWMKVDDUJ&quot;}" data-component-name="LatexBlockToDOM"></div><h2>Fee Accounting in JOE v2</h2><p>There are two types of fees charged in <em>JOE v2</em>: the normal swap fee and the composition fee.</p><h3>Normal Swap Fee</h3><p>Swapping tokens in the <em>JOE v2 Liquidity Book</em> incurs a certain amount of fees. The basic rate applied to the total swap amount is defined as <strong>fs</strong>:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_s=f_b+f_v&quot;,&quot;id&quot;:&quot;YGCOCTDJTG&quot;}" data-component-name="LatexBlockToDOM"></div><p>Here, <strong>fb</strong>&#8203; is a fixed rate, and <strong>fv</strong>&#8203; is a variable rate used to measure market volatility. For the purposes of this blog post, we can safely assume that <strong>fs</strong>&#8203; is a fixed percentage for normal swaps.</p><h3>Composition Fee</h3><p>Another situation that requires fee accounting is when liquidity providers increase their positions in the current active bin.</p><blockquote><p><em>Why do we need to charge fees when adding liquidity?</em></p></blockquote><p>Remember that the liquidity of a certain bin with price <strong>Pi</strong> is defined as <strong>L = Pi &#183; x + y</strong>. So, the liquidity for a given bin can be directly calculated from the amount of each token and is not related to the bin composition <strong>c</strong>. In theory, we can add some tokens x and y with a random composition rate to serve as supplied liquidity.</p><p>Liquidity providers (LPs) supply liquidity to a specific bin with a certain ratio of trading tokens. However, the ratio of tokens in the liquidity supplied by LPs can differ from the original ratio of tokens in that bin. A composition fee should be charged for this discrepancy between the composition of the supplied liquidity and the composition of the bin itself.</p><h4>Demo - Why Charge a Composition Fee?</h4><p>Here is a demo showcasing a liquidity provider, Alex, supplying liquidity into the bin with a different composition factor:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ICVX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ICVX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ICVX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ICVX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ICVX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ICVX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg" width="1420" height="572" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:572,&quot;width&quot;:1420,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:124508,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ICVX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ICVX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ICVX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ICVX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc84a2634-f02f-47b5-884c-bfa6453b9fe3_1420x572.jpeg 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><ol><li><p>Assume the current bin's liquidity <strong>L'</strong> is purely composed of token Y (rounded rectangle in green shadow with solid border), resulting in the bin composition ratio <strong>c</strong> equals 1.</p></li><li><p>Now Alex adds liquidity <strong>&#916;L</strong> into the current bin's liquidity. <strong>&#916;L </strong>is purely composed of token X (in purple shadow with a solid border). After that, the total liquidity increases to <strong>L' + &#916;L</strong> and the bin composition <strong>c</strong> decreases to 0.3 (for demonstration purposes). It implies that Alex gains a 70% share of the current bin's liquidity. </p></li><li><p>Immediately after adding liquidity, Alex decides to remove his 70% share. When liquidity providers (LPs) burn their shares, they should be rewarded with a proportionate amount of the total bin reserves based on their share. Thus, Alex receives 70% of both token X and token Y in the bin reserve (dotted border).</p></li><li><p>In the end, the liquidity of the current bin is still <strong>L'. </strong>Essentially, it is equivalent for Alex to just swap 70% of token Y for token X in the original bin.</p></li></ol><p>If Alex is not charged any fees for his initial liquidity entrance, he effectively performs a swap without incurring a fee. This scenario highlights the importance of charging composition fees in preventing such fee-less arbitrage opportunities.</p><h4>Charging the Composition Fee</h4><p><em>Trader Joe v2</em> does its best to empower its liquidity providers to add liquidity with a random composition rate. It swaps LPs' liquidity to a target ratio and charges an extra composition fee <strong>fc</strong>:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;f_c=f_s\\times(1+f_s)&quot;,&quot;id&quot;:&quot;ANDABLMNYZ&quot;}" data-component-name="LatexBlockToDOM"></div><p>where <strong>fs</strong> is the original fee being charged as if it is a normal swap.</p><p>In short, the actual composition fee rate <strong>fc</strong> is a bit higher than the normal swapping fee rate, which is somewhat reasonable because it is a pretty convenient and practical utility for LPs.</p><p>According to <em>Trader Joe v2</em>'s whitepaper:</p><blockquote><p>Liquidity that is added <em>to the active bin</em> will <strong>automatically be swapped</strong> across reserves <em>if the composition is not equal to the bin&#8217;s composition</em>. The amount swapped is calculated so that the resulting assets in the bin equal those that would result if the user were to swap prior to adding liquidity. The amount swapped <strong>incurs a fee</strong> that approximates the current market swap fee.</p></blockquote><p>As <em>JOE v2</em> does not perform the actual swap, it acts as if the provided liquidity <strong>&#916;L</strong> is swapped to a target composition and charges the corresponding swap amount by the composition fee rate.</p><h2>Compensation from Composition Fees</h2><p>Now let's go back to the arbitrager Alex. When Alex adds his liquidity <strong>&#916;L</strong>, a subtle amount of extra fee (in yellow shadow) is deducted from the input X, remaining <code>amountsIn</code> to be calculated as the effective liquidity amount that Alex provides.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zFPH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zFPH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zFPH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zFPH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zFPH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zFPH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg" width="1102" height="823" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:823,&quot;width&quot;:1102,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:105521,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zFPH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zFPH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zFPH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zFPH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0b689af-034c-4f26-9e5d-adc6ad98ee50_1102x823.jpeg 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></p><p>Assume there's a target composition rate <strong>c'</strong> that is a bit larger than 0.3 (the final composition).</p><p>To absorb Alex's liquidity with a different composition, <em>Trader Joe v2</em> first swaps the original liquidity <strong>L'</strong> to the target composition <strong>c'</strong> with no fee. Then Alex also swaps his liquidity <strong>&#916;L</strong> to the target composition <strong>c'</strong> with some composition swap fee.</p><p>Since all quote token Y in the final liquidity bin is composed of existing tokens Y in the original liquidity bin, the following equation holds true:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;(L'+\\Delta L)\\times c' = L'&quot;,&quot;id&quot;:&quot;AXDJSBGWXC&quot;}" data-component-name="LatexBlockToDOM"></div><p>After the swap, the amount of token X in the original liquidity equals the amount of token Y that Alex swapped:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;L'\\times(1-c')=\\Delta L\\times c'&quot;,&quot;id&quot;:&quot;WRLHNNGNLE&quot;}" data-component-name="LatexBlockToDOM"></div><p>At this point, there is no further obstacles for Alex to enter his liquidity. Since the composition factor <strong>c'</strong> is the same, adding liquidity is literally the same to adding the corresponding trading token pair. &nbsp;</p><h2>Implementation and the Hidden Flaw</h2><p>So that's all for composition fee accounting when adding liquidity. It's time to cast light on <em>Trader Joe v2</em>'s actual implementation, including the flaw.</p><p>In the case of entering liquidity, <code>_mintBins()</code> will be called by the public <code>mint()</code> function and for each bin in the LP's provided range, <code>_updateBin()</code> is called to calculate LP's share for this bin.</p><pre><code>function _updateBin(...) returns (uint256 shares, ...) {
    ...

    (shares, amountsIn) = binReserves.getSharesAndEffectiveAmountsIn(...);

    if (id == activeId) {
        ...

        bytes32 fees = binReserves.getCompositionFees(...);

        if (fees != 0) {
            uint256 userLiquidity = amountsIn.sub(fees).getLiquidity(price);
            uint256 binLiquidity = binReserves.getLiquidity(price);

            shares = userLiquidity.mulDivRoundDown(supply, binLiquidity);
            ...
        }
    }

    ...
}</code></pre><ul><li><p><code>getSharesAndEffectiveAmountsIn()</code> calculates the corresponding share <code>shares</code> for LP's added liquidity and the actual trading token reserve change <code>amountsIn</code>. &nbsp;</p></li><li><p><code>getCompositionFees()</code> calculates the corresponding composition fee for the swap to the target composition factor.</p></li><li><p>the final LP's <code>shares</code> is <code>userLiquidity</code> / <code>binLiquidity</code></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_!lT30!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lT30!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lT30!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lT30!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lT30!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lT30!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg" width="1348" height="745" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:745,&quot;width&quot;:1348,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:123584,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lT30!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 424w, https://substackcdn.com/image/fetch/$s_!lT30!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 848w, https://substackcdn.com/image/fetch/$s_!lT30!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!lT30!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e224d9-ed4b-4730-9e18-ef4c232b3964_1348x745.jpeg 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><h2>Impact of Fee Misallocation</h2><p>The subtle insight is that the composition <code>fee</code> for the swap is not involved in the share calculation. Three parts make up the total liquidity of the bin: <code>binLiquidity</code>, <code>userLiquidity </code>and <code>fee</code>. However, the liquidity provider&#8217;s share is simply put as <code>userLiquidity / binLiquidity.</code>The left-alone fee, which should only be claimable by existing liquidity providers, now is silently shared across all liquidity providers.</p><p>The correct way to calculate LP&#8217;s share is <code>userLiquidity / ( binLiquidity + fee)</code></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FYrq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FYrq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FYrq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FYrq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FYrq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FYrq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg" width="1456" height="760" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:760,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:125906,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FYrq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FYrq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FYrq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FYrq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc87960c-d2de-45a0-a6f1-bcdf03d424d6_1505x786.jpeg 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>Alex, who entered 70% liquidity in our previous example, will be able to have a 70% discount on the swap fees he has just paid. In an ideal situation when <code>userLiquidity</code> / <code>binLiquidity</code> is large enough, like +&#8734;, all composition fees will be returned to the LP. Arbitrager will be able to perform fee-free swaps by first entering and then immediately withdraw liquidity.</p><h2>Fixing </h2><p>The correct implementation is to put the composition fee into share calculation. Since the composition fee is reserved for the previous LPs, the fee parameter should also be accounted for in the denominator:</p><div class="latex-rendered" data-attrs="{&quot;persistentExpression&quot;:&quot;userLiquidity / ( binLiquidity + fee)&quot;,&quot;id&quot;:&quot;BPVHZBXEHE&quot;}" data-component-name="LatexBlockToDOM"></div><p>In commit <a href="https://github.com/traderjoe-xyz/joe-v2/commit/7e5b0b49440f45d2ec8650173083fa843d0e9d7d?diff=unified&amp;w=0">7e5b0b494</a>, the Trader Joe Team has already fixed this issue:</p><pre><code>if (fees != 0) {
    uint256 userLiquidity = amountsIn.sub(fees).getLiquidity(price);
-   uint256 binLiquidity = binReserves.getLiquidity(price);

-   shares = userLiquidity.mulDivRoundDown(supply, binLiquidity);
    bytes32 protocolCFees = fees.scalarMulDivBasisPointRoundDown(parameters.getProtocolShare());

    if (protocolCFees != 0) {
        amountsInToBin = amountsInToBin.sub(protocolCFees);
        _protocolFees = _protocolFees.add(protocolCFees);
    }

+   uint256 binLiquidity = binReserves.add(fees.sub(protocolCFees)).getLiquidity(price);
+   shares = userLiquidity.mulDivRoundDown(supply, binLiquidity);

    parameters = _oracle.update(parameters, id);
    _parameters = parameters;</code></pre><p>After calculating the <code>protocolCFees</code>, which is reserved for the protocol itself, the code adds <code>fees.sub(protocolCFees)</code> to the <code>binLiquidity</code>. This step ensures that only the fees excluding the protocol fees are added to the liquidity pool. Then, it calculates the user's actual share of the liquidity pool. This process is precisely how it is intended to function.</p><h2>Timeline</h2><ul><li><p>2023-11 Reported the issue to the <em>Trader Joe v2</em> on <em><strong>Immunefi</strong></em>.</p></li><li><p>2024-07 the Trader Joe Team has fixed this issue in commit <a href="https://github.com/traderjoe-xyz/joe-v2/commit/7e5b0b49440f45d2ec8650173083fa843d0e9d7d">7e5b0b494</a>.</p></li></ul><h2>Reference</h2><ul><li><p><a href="https://github.com/traderjoe-xyz/LB-Whitepaper/blob/main/Joe%20v2%20Liquidity%20Book%20Whitepaper.pdf">Joe v2 Whitepaper</a></p></li></ul><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.offside.io/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Offside Labs&#8217; Security Insights! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[One Key Bug in OneKey Mini]]></title><description><![CDATA[Delve into the security vulnerabilities of OneKey Mini hardware wallets. Through detailed analysis and hands-on experimentation, we discovered that while remote code execution threats are rare, numerous risks arise when an attacker gains physical access to the device.]]></description><link>https://blog.offside.io/p/one-key-bug-in-onekey-mini</link><guid isPermaLink="false">https://blog.offside.io/p/one-key-bug-in-onekey-mini</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Thu, 30 May 2024 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8cad33ba-1c93-4e83-b917-e61e0a0f9c8b_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"Not your keys, not your crypto." That's the lesson a friend of mine learned after losing a significant amount due to the collapse of FTX. He vowed that he would never put his life savings to a centralized exchange again. But is a hardware wallet the ultimate solution?</p><p>During Black Friday sales, he purchased several hardware wallets at a discount and sent me a <a href="https://onekey.so/products/onekey-mini-hardware-wallet/">OneKey Mini</a> for my security expertise. As a new Web3 hacker with extensive experience in Web2, I don't trust the security of anything without thorough investigation.</p><p>Together with my colleagues at <a href="https://twitter.com/Offside_Labs">Offside Labs</a>, we delved into hardware wallet vulnerability research and discovered significant security issues. In this blog post, we will share the first journey and findings of our research.</p><h1>What We Learn</h1><p>So what is a hardware wallet? A <a href="https://www.coinbase.com/learn/crypto-basics/what-is-a-hardware-wallet">Hardware Wallet</a> is a specialized device designed to secure digital currencies. Hardware wallets store sensitive information, like recovery mnemonics, within the secure computational compents of the device. Private keys are never exposed to the internet, thus reducing the risk of online threats and keeping your assets secure.</p><p><a href="https://trezor.io/">Trezor</a> is a famous hardware wallet manufacturer that I knew about even before the commence of my web3 research. It is an actively maintained open-source project and it has been forked by many other competitor wallet manufacturers. <a href="https://onekey.so/">OneKey</a> also forked Trezor's repository for their own products.</p><p>As a hardware wallet project which was launched 12 years ago, I am pretty confident that I can easily find some previously discovered vulnerabilities. I took some time to make an investigation on its topic and summarized the following attack surfaces of hardware wallets.</p><ul><li><p><strong>Trezor Side-channels</strong>. Prior to firmware version 1.3.1 (around 2015), Trezor was vulnerable to side-channel attacks leveraging information obtained from power fluctuations during the public key computation process. I read abount this attack surface from <a href="https://jochen-hoenicke.de/crypto/trezor-power-analysis/">Jochen-Hoenicke's blog</a></p></li><li><p><strong>Trezor Secrets from SRAM</strong>. Some old version of Trezor failed to wipe out the content of SRAM when the hardware wallet is rebooted, so hackers are capable to recover some sensitive information. <a href="https://saleemrashid.com/2017/08/17/extracting-trezor-secrets-sram/">Saleem Rashid</a> detailed a process of leaking private secrets from SRAM by doing hardware reset.</p></li><li><p><strong>KeepKey Glitching</strong>. STM32 has a security mechanism known as Read Protection (RDP). <a href="https://media.ccc.de/v/35c3-9563-wallet_fail">Wallet.Fail</a> and <a href="https://www.blackhat.com/us-19/briefings/schedule/#chipfail---glitching-the-silicon-of-the-connected-world-15192">Chip.Fail</a> demonstrated that downgrading RDP can reliably be performed at boot with voltage glitching. Once a device is at RDP1, its SRAM can be read out. You can ead more about this attack surface on <a href="https://blog.kraken.com/product/security/flaw-found-in-keepkey-crypto-hardware-wallet-part-2">Kraken's blog post</a>.</p></li><li><p><strong>KeepKey Buffer Overflow</strong>. Christian Reitter has an excellent series of <a href="https://blog.inhq.net/posts/keepkey-CVE-2021-31616">blog post</a> on a serious buffer overflow vulnerability in the KeepKey hardware wallet. In specific <a href="https://blog.inhq.net/posts/faulty-stack-canary-arm-systems/#the-initial-vulnerability-discovery">versions</a> of arm-none-eabi-gcc, the stack canary code is incorrectly generated, resulting in a fixed canary value that can be easily bypassed.</p></li><li><p><strong>OneKey Man-in-the-Middle</strong>. <a href="https://www.youtube.com/watch?v=b8OrakRJmHE">Unciphered</a> demonstrated a critical security vulnerability for the OneKey wallet. This security vulnerability allowed anyone with physical access to the hardware wallet to swipe its mnemonics by inserting a particular piece of hardware between the CPU and the secure unit of the wallet.</p></li></ul><p>The discussion of these attack surfaces highlights that while hardware wallets are generally secure for storing cryptocurrency, there can be vulnerabilities that could potentially expose your private keys. Generally speaking, remote code execution vulnerabilities + physical access to your hardware wallet = takeover of your crypto assets there.</p><h1>What We Find</h1><p>I'm now well aware of what can go wrong with a hardware wallet. It's time to dive in and play with my little OneKey Mini.</p><p>OneKey Mini, priced $1 less than its Trezor competitor <a href="https://trezor.io/trezor-model-one">Trezor Model One</a>, is one of the cheapest hardware wallets available in the market. Popular in Chinese-speaking regions, it offers additional features like a Secure Element (SE) and Chinese language support. However, it is just the addition of these relevent code and extra features that has expanded its attack surface and introduced risks due to their unsatisfying code quality. We can dive into its firmware code <a href="https://github.com/OneKeyHQ/firmware/tree/mini">here</a>.</p><h2>One Pitfall</h2><p>Due to the fact that OneKey is a fork of the Trezor project, much of their code are the same and we can easily figure out which part of the code is added by OneKey developers. The first thought occured to me was that I can figure out how OneKey implement their additional Chinese language support functionality, compared to the corresponding Trezor code. I quickly came across this <code>font_data_read()</code> function, which reads in the font files from the additional flash storage by calling inner <code>flash_read_enc()</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bE7r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bE7r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 424w, https://substackcdn.com/image/fetch/$s_!bE7r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 848w, https://substackcdn.com/image/fetch/$s_!bE7r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 1272w, https://substackcdn.com/image/fetch/$s_!bE7r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bE7r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!bE7r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 424w, https://substackcdn.com/image/fetch/$s_!bE7r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 848w, https://substackcdn.com/image/fetch/$s_!bE7r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.png 1272w, https://substackcdn.com/image/fetch/$s_!bE7r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d3cbf71-ef12-452d-b71d-9a094a147ea3_1920x960.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>I analyzed all the functions that are related to flash reading and writing. Then I stumbled on these two additional "(fac<strong>ot</strong>ry) = true" constraints on <code>MessageType_SpiFlashWrite</code> and <code>MessageType_SpiFlashRead</code> message types. I mean this is a <em>factory</em>, not <strong>facotry</strong> right? I guess it is a typo. &#129300;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s40R!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s40R!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 424w, https://substackcdn.com/image/fetch/$s_!s40R!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 848w, https://substackcdn.com/image/fetch/$s_!s40R!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 1272w, https://substackcdn.com/image/fetch/$s_!s40R!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s40R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!s40R!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 424w, https://substackcdn.com/image/fetch/$s_!s40R!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 848w, https://substackcdn.com/image/fetch/$s_!s40R!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.png 1272w, https://substackcdn.com/image/fetch/$s_!s40R!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F717072cf-7b47-4a2f-b24b-fb8e600d8874_1919x960.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>I searched for both <code>factory</code> and <code>facotry</code> in the project to prove my guessing. This <code>(facotry) = true</code> constraint suggests that the developers intended to limit certain SpiFlash read/write operations to <strong>Factory</strong> Mode. This mode is active before the products are distributed to customers. While the <code>getattr</code> in <code>messages_map.py</code> correctly spell <em>factory</em>, there's a typo in the <code>messages.proto</code> file. As a result, <code>MessageType_SpiFlashWrite</code> and <code>MessageType_SpiFlashRead</code> are mistakenly accessible in every OneKey Mini product.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5x0i!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5x0i!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 424w, https://substackcdn.com/image/fetch/$s_!5x0i!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 848w, https://substackcdn.com/image/fetch/$s_!5x0i!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 1272w, https://substackcdn.com/image/fetch/$s_!5x0i!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5x0i!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png" width="1456" height="730" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:730,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!5x0i!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 424w, https://substackcdn.com/image/fetch/$s_!5x0i!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 848w, https://substackcdn.com/image/fetch/$s_!5x0i!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.png 1272w, https://substackcdn.com/image/fetch/$s_!5x0i!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5178cec-1b65-4caa-9423-4aa3e76136a5_4404x2208.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>We accidentally gained access to the <code>fsm_msgSpiFlashRead</code> and <code>fsm_msgSpiFlashWrite</code> functions. These should only be accessible in factory mode.</p><h2>One Overflow</h2><p>I carefully inspected these two functions. Within the <code>fsm_msgSpiFlashRead</code> function, I found that there's an absence of validation for the <code>msg</code> parameter regarding its length. This oversight implies that when storing user input data into the variable <code>resp</code> with function <code>msg_write</code>, those data can be written past the boundaries of the allocated buffer.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VLH_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VLH_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 424w, https://substackcdn.com/image/fetch/$s_!VLH_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 848w, https://substackcdn.com/image/fetch/$s_!VLH_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!VLH_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VLH_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!VLH_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 424w, https://substackcdn.com/image/fetch/$s_!VLH_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 848w, https://substackcdn.com/image/fetch/$s_!VLH_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!VLH_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cce73aa-9a81-409d-ace7-721954c67b34_4400x2200.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>Furthermore, the presence of the <code>fsm_msgSpiFlashWrite</code> function opens the possibility for a hacker to manipulate the overflowed content. This function allows us to write arbitrary data into any address in the flash memory, at our complete disposal.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oObG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oObG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 424w, https://substackcdn.com/image/fetch/$s_!oObG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 848w, https://substackcdn.com/image/fetch/$s_!oObG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 1272w, https://substackcdn.com/image/fetch/$s_!oObG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oObG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!oObG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 424w, https://substackcdn.com/image/fetch/$s_!oObG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 848w, https://substackcdn.com/image/fetch/$s_!oObG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.png 1272w, https://substackcdn.com/image/fetch/$s_!oObG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0e957b65-550a-4537-882a-59fd11130ef2_4400x2199.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>Things were looking promising here, yet the exploit's effectiveness hinged on the ability to overwrite meaningful data with the overflow. I promptly shared my findings with my teammates and collaborated on addressing a legitimate exploit.</p><h2>The Exploit</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yzaF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yzaF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 424w, https://substackcdn.com/image/fetch/$s_!yzaF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 848w, https://substackcdn.com/image/fetch/$s_!yzaF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!yzaF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yzaF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png" width="1456" height="724" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!yzaF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 424w, https://substackcdn.com/image/fetch/$s_!yzaF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 848w, https://substackcdn.com/image/fetch/$s_!yzaF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!yzaF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d14524d-820c-4895-90f6-683c87a8421c_4422x2200.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>The stack protection mechanism is active but the overflowed object <code>resp</code> didn't lie on the stack, so there was no concern to circumvent the stack protection mechanism in the exploit. Upon examining the compiled and symbolized binary file, we notice that the <code>resp</code> object was located at memory address <code>0x20009d58</code>. Interestingly, not far from this location was the <code>timer_array</code> at <code>0x2001659c</code>. This proximity suggests a potential target for the overflow to corrupt or manipulate. The <code>timer_func</code> is defined as:</p><pre><code>typedef void (*timer_func)(void);

#define TIMER_NUM 4

typedef struct {
&nbsp; char name[32];
&nbsp; uint32_t current;
&nbsp; uint32_t cycle;
&nbsp; timer_func fp;
} TimerDsec;

TimerDsec timer_array[TIMER_NUM] = {0};
</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-M4w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-M4w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 424w, https://substackcdn.com/image/fetch/$s_!-M4w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 848w, https://substackcdn.com/image/fetch/$s_!-M4w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!-M4w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-M4w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-M4w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 424w, https://substackcdn.com/image/fetch/$s_!-M4w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 848w, https://substackcdn.com/image/fetch/$s_!-M4w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!-M4w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab564d61-8c3c-43b0-83ee-5e67ba728872_4400x2200.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>In this particular scenario, the function pointer <code>fp</code> is executed by the system's <code>sys_tick_handler</code>. This means that by strategically overwriting the contents of <code>fp</code>, it becomes possible to manipulate the Program Counter to execute arbitrary code. This capability is crucial for gaining control over the system's operations. However, we encountered an initial obstacle. At system startup, the firmware security function, <code>mpu_config_firmware</code>, configures the memory segment that includes <code>resp</code> (where we intended to place our payload) to be <strong>read-write</strong> but explicitly sets it to <strong>execute never</strong>. This security measure prevents execution of any code that resides in this segment, effectively safeguarding the system against unauthorized code execution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IC5C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IC5C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 424w, https://substackcdn.com/image/fetch/$s_!IC5C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 848w, https://substackcdn.com/image/fetch/$s_!IC5C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!IC5C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IC5C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!IC5C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 424w, https://substackcdn.com/image/fetch/$s_!IC5C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 848w, https://substackcdn.com/image/fetch/$s_!IC5C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.png 1272w, https://substackcdn.com/image/fetch/$s_!IC5C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcdb25699-c9d8-4f05-869f-e9c32c1284e3_4400x2200.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>Despite this security configuration, having control over the PC provided a significant advantage. It allowed us to circumvent the Memory Protection Unit (MPU) settings that were initially blocking our attempts to execute code from the <code>resp</code> segment. By executing the <code>mpu_config_off</code> function, we could disable the MPU restrictions entirely. This action removed the execution barriers on the <code>resp</code> segment. With these restrictions lifted, we were able to redirect the PC to execute shellcode specifically placed within <code>resp</code>. This maneuver effectively bypassed the system's initial security mechanisms, allowing us to execute our custom shellcode and manipulate the system as needed.</p><h2>The Demo</h2><p>Here is a demo of how we used this vulnerability to access the mnemonic before unlocking the OneKey Mini.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;009dc33f-9a83-4a22-8850-9b6a8dd4ecc3&quot;,&quot;duration&quot;:null}"></div><p>During my research and development of this exploit, guidance from my <a href="https://twitter.com/Offside_Labs">Offside Labs</a> colleagues proved invaluable. Their top-tier expertise and remarkable experience significantly enhanced this enjoyable research journey. Immersed in the vibrant atmosphere of Offside Labs, I've found an invigorating desire to dedicate myself to the enthralling world of web3.</p><h1>Timeline</h1><p>Here is the complete timeline of our research and the vulnerability disclosure process:</p><ul><li><p>2023-11-09: Purchased OneKey Mini.</p></li><li><p>2023-11-15: Began reviewing the source code of the OneKey Mini and - discovered the bug.</p></li><li><p>2023-11-16: Confirmed the severity of the bug by controlling the PC - register.</p></li><li><p>2023-11-22: Completed the first version of the demo video.</p></li><li><p>2023-12-05: Reported the vulnerability to OneKey.</p></li><li><p>2023-12-20: <a href="https://github.com/OneKeyHQ/firmware/pull/499">Patch</a> was merged.</p></li><li><p>2023-12-25: Received bounty ($5k, top tier) for the vulnerability report.</p></li><li><p>2024-01: Mandatory updates were rolled out.</p></li></ul><p>OneKey has generously set their top-tier bounty for this vulnerability, offering a reward of $5,000.</p><p>Following this discovery, my confidence in using hardware wallets to protect my cryptocurrencies was somewhat shaken. I still harbor doubts about whether these devices are truly the best option for safeguarding my investments, especially if I were to lose the devices one day.</p><h1>References</h1><ul><li><p><a href="https://jochen-hoenicke.de/crypto/trezor-power-analysis/">Extracting the Private Key from a Trezor</a></p></li><li><p><a href="https://blog.kraken.com/product/security/kraken-identifies-critical-flaw-in-trezor-hardware-wallets">Kraken Identifies Critical Flaw in Trezor Hardware Wallets</a></p></li><li><p><a href="https://media.ccc.de/v/35c3-9563-wallet_fail">wallet.fail - Hacking the most popular cryptocurrency hardware wallets</a></p></li><li><p><a href="https://blog.kraken.com/product/security/flaw-found-in-keepkey-crypto-hardware-wallet">Inside Kraken Security Labs: Flaw Found in Keepkey Crypto Hardware Wallet</a></p></li><li><p><a href="https://blog.kraken.com/product/security/flaw-found-in-keepkey-crypto-hardware-wallet-part-2">Inside Kraken Security Labs: Flaw Found in Keepkey Crypto Hardware Wallet (Part 2)</a></p></li><li><p><a href="https://www.blackhat.com/us-19/briefings/schedule/#chipfail---glitching-the-silicon-of-the-connected-world-15192">Chip.Fail - Glitching the Silicon of the Connected World</a></p></li><li><p><a href="https://saleemrashid.com/2017/08/17/extracting-trezor-secrets-sram/">Extracting TREZOR Secrets from SRAM</a></p></li><li><p><a href="https://www.riscure.com/hacking-ultra-secure-hardware-cryptowallet/">Hacking the ultra-secure hardware cryptowallet</a></p></li><li><p><a href="https://blog.inhq.net/posts/keepkey-CVE-2021-31616/#the-vulnerability">KeepKey Stack Buffer Overflow Vulnerability (CVE-2021-31616)</a></p></li><li><p><a href="https://blog.inhq.net/posts/faulty-stack-canary-arm-systems/#the-initial-vulnerability-discovery">Faulty Stack Smashing Protection on ARM Systems</a></p></li><li><p><a href="https://blog.onekey.so/write-original-firmware-55aedd7446c5">OneKey Masa - Write original firmware</a></p></li><li><p><a href="https://github.com/trezor/trezor-firmware">trezor/trezor-firmware</a></p></li><li><p><a href="https://github.com/OneKeyHQ/firmware">OneKeyHQ/firmware</a></p></li><li><p><a href="https://cryptopotato.com/unciphered-reveals-now-patched-vulnerability-in-onekey-wallet/">Unciphered Reveals Now-Patched Vulnerability in OneKey Wallet</a></p></li></ul>]]></content:encoded></item><item><title><![CDATA[Saga of Saga – Part 2: Digging Into Solana's Smartphone Security]]></title><description><![CDATA[Explore the intricate security designs of Solana's Web3 Smartphone, 'Saga', with a deep dive into its unique features like Seed Vault and the challenges posed by mobile crypto wallets.]]></description><link>https://blog.offside.io/p/saga-of-saga-part-2-digging-into-solana</link><guid isPermaLink="false">https://blog.offside.io/p/saga-of-saga-part-2-digging-into-solana</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Sat, 16 Dec 2023 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f3148834-0a86-4569-b278-3e130456e246_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Recap</h1><p>In the <a href="https://blog.offside.io/p/saga-of-saga-part-1-unlocking-the-debate">first part</a> of our 'Saga of Saga' series, we initiated a discussion on the concept of true vulnerabilities, setting the stage for a deeper analysis. Now, in Part 2, we'll delve further into Saga's robust security design and implementation, appreciating its resilience even in the face of potential bootloader vulnerabilities.&nbsp;</p><h1>Security Hurdles in Mobile Crypto Wallets</h1><p>Let's now navigate the technical maze of Saga. We find that Saga is built upon the Android Open Source Project (AOSP). It's almost a mirror image of your regular Android devices, with two notable features: the dApp Store and the Seed Vault. The dApp Store serves as the gateway to the vast ecosystem of Solana (a wonderland we might explore in future blogs), while the Seed Vault significantly boosts the device's security level.&nbsp;&nbsp;</p><h2>Incorporating the Seed Vault: A Look at System Settings&nbsp;</h2><p>The Seed Vault, listed first in the System Settings, is designed to support the creation and management of your crypto wallet's seed. But it's far more than just a system-level application; it's your gateway to a more secure trusted zone.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CWC6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CWC6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 424w, https://substackcdn.com/image/fetch/$s_!CWC6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 848w, https://substackcdn.com/image/fetch/$s_!CWC6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 1272w, https://substackcdn.com/image/fetch/$s_!CWC6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CWC6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png" width="1456" height="1621" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1621,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:588520,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CWC6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 424w, https://substackcdn.com/image/fetch/$s_!CWC6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 848w, https://substackcdn.com/image/fetch/$s_!CWC6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 1272w, https://substackcdn.com/image/fetch/$s_!CWC6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed558d45-bbc3-4c4c-a752-d942bcab987b_1820x2026.png 1456w" sizes="100vw" fetchpriority="high"></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><h2>Untrusted Apps: No Access to Trusted Computing&nbsp;</h2><p>You might wonder, what sets the Seed Vault apart from the standard crypto wallet on Android? Recall our recent discussion about the Trusted Computing Base (TCB)? Unfortunately, almost all mobile wallets fail to fully adhere to the TCB design principle.&nbsp;&nbsp;</p><p>Some simply have no understanding of trusted computing. They might even store passwords and secret keys in plaintext. Others find themselves limited by the capabilities of the underlying operating system. Take Apple, for instance. While it does possess a Secure Enclave Processor (SEP) on iOS for handling cryptographic operations on sensitive data, it's exclusively used by its native apps. An unofficial app does not enjoy the luxury of utilizing the SEP on its own will.&nbsp;</p><p>On Android devices, you could leverage the Hardware-backed Keystore API to do crypto related operations, so that the secret keys never leave the Trusted Execution Environment (TEE).&nbsp;</p><p>Solana utilizes ed25519, an elliptic curve designed for use with EdDSA. This was recently included in <a href="https://csrc.nist.gov/pubs/fips/186-5/final">FIPS 186-5</a>, the Digital Signature Standard (DSS) issued by National Institute of Standards and Technology (NIST), as of February 2023. Notably, <a href="https://http//1.%09https/cs.android.com/android/platform/superproject/main/+/main:frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java%3Bl=147-153">ed25519 is supported</a> in the Hardware-backed Keystone on Android.&nbsp;</p><p>However, just because ed25519 is supported in the Android framework does not automatically give you the ability to use EdDSA. It's up to the vendor of the underlying chipset to decide whether to implement the corresponding cryptographic operations. Surprisingly, even the Google Tensor chipset that comes with the Google Pixel 6 doesn't provide support for EdDSA yet.&nbsp;</p><p>Considering the significant fragmentation among Android vendors, it's unwise for a mobile wallet app to solely depend on hardware-backed features.&nbsp;</p><h2>Crypto Compatibilities of Crypto Currencies&nbsp;</h2><p>In fact, most apps are unable to leverage the Hardware-backed Keystore for signing purposes; their use is largely confined to secure private key storage!&nbsp;This is because major cryptocurrencies, such as BTC and ETH, are intentionally designed to be incompatible with certain standard encryption protocols.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wpc9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wpc9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wpc9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wpc9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wpc9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wpc9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Securing Web3 Mobile Wallets with TEE: Delving into the Security Guarantees and Real-world Implementation Pitfalls, Yuan Zhuang@Certik, MOSEC2023&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Securing Web3 Mobile Wallets with TEE: Delving into the Security Guarantees and Real-world Implementation Pitfalls, Yuan Zhuang@Certik, MOSEC2023" title="Securing Web3 Mobile Wallets with TEE: Delving into the Security Guarantees and Real-world Implementation Pitfalls, Yuan Zhuang@Certik, MOSEC2023" srcset="https://substackcdn.com/image/fetch/$s_!wpc9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 424w, https://substackcdn.com/image/fetch/$s_!wpc9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 848w, https://substackcdn.com/image/fetch/$s_!wpc9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!wpc9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb6e6135d-aa58-4a22-b232-5c5e0edf07de_4096x2304.jpeg 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>The signing algorithm implemented on iOS and Android devices is ECDSA-secp256r1, also known as NIST P-256, which is recommended by the NIST. Worries regarding the NSA&#8217;s potential to crack the crypto system have been present since cryptocurrencies were first created. As a result, BTC and ETH deliberately use an alternative signing algorithm, ECDSA-secp256k1. However, this "mitigation" forces mobile apps to extract the credentials from the TEE and operate within a less secure environment.&nbsp;</p><p>The threats present in an insecure computing environment aren't solely from malicious attackers; they can also originate from careless or misbehaving wallet developers. The <a href="https://slope-finance.medium.com/slope-wallet-sentry-vulnerability-digital-forensics-and-incident-response-report-d7a5904e5a39">Slope Wallet Sentry Vulnerability</a> serves as an example of this, having occurred within a Solana mobile wallet. In this case, the seed phrases for users' private keys, stored in plaintext, were unintentionally transmitted to a centralized server without encryption. Thousands of wallets were compromised, and millions of funds were stolen due to the exposed credentials.&nbsp;</p><h2>Securing the Unsecure: The Potential of Seed Vault&nbsp;</h2><p>Seed Vault implements centralized, mandatory access control for users' credentials. Rather than dealing with the keys directly, the wallet must make requests to the Seed Vault to sign any transactions. This approach significantly reduces the attack surface within mobile wallet applications.&nbsp;</p><p>At present, the Seed Vault exclusively supports Solana, but it has the potential to resolve compatibility issues associated with ECDSA signing algorithms for other crypto currencies. They could integrate any wallet-specific cryptographic operations within a Trusted Applet (TA), leveraging the crypto API made available by Qualcomm Secure Execution Environment (QSEE). As the vendor of Saga, they are both privileged and obligated to provide the most secure solutions.&nbsp;</p><p>Another significant yet often overlooked risk within the mobile system is that the wallet app could suffer from a UI forgery attack. A malicious app could draw another layer of graphics over the wallet app, presenting fraudulent transaction confirmations or signature requests. This could lead to user interactions being misdirected or intercepted. The ultimate solution to this issue is using a Trusted UI, directly provided by the TEE. Once again, this calls for the vendor's privilege.&nbsp;</p><p>&nbsp;There are many tasks that vendors can and should do. What have they done for Saga? To understand this, we need to explore the security-related system design principles of Android.&nbsp;</p><h1>Exploring Android's Normal World</h1><p>Android devices operate on various privilege levels with a range of programs:&nbsp;&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YE9E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YE9E!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 424w, https://substackcdn.com/image/fetch/$s_!YE9E!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 848w, https://substackcdn.com/image/fetch/$s_!YE9E!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 1272w, https://substackcdn.com/image/fetch/$s_!YE9E!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YE9E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png" width="1456" height="1050" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1050,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!YE9E!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 424w, https://substackcdn.com/image/fetch/$s_!YE9E!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 848w, https://substackcdn.com/image/fetch/$s_!YE9E!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.png 1272w, https://substackcdn.com/image/fetch/$s_!YE9E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dab1c0c-eda7-4bbc-bf00-d013da86a4fe_2864x2066.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><h2>User Space Programs (EL-0)</h2><p>These are the most common applications on your device. They fall into four categories:&nbsp;&nbsp;</p><ol><li><p>Untrusted Apps: Installed or downloaded from the dApp Store, these apps are typically not considered trustworthy. For example, <code>dAppStore</code> and <code>Solflare</code> are two such apps.&nbsp;</p></li><li><p>Preinstalled Apps: Preinstalled on the Android ROM, these apps may be vendor-certified but should not possess extra privileges. <code>SeedVaultManager</code> and <code>SolanaSettings</code> are examples of this category.&nbsp;</p></li><li><p>System Apps: Builtin apps on vanilla Android, or selected by the vendor, these apps have elevated permissions and control sensitive system settings. <code>WalletProvider</code> and <code>SeedVaultServiceApp</code> are examples of system apps.&nbsp;</p></li><li><p>System/Vendor Services: Different from the apps, these services interact with Android's binder IPC mechanism, offering key functionalities and operating within restricted sandboxes. For example, <code>vendor.osom.seedvault-service</code> and <code>vendor.qti.hardware.trustedui</code> are two such services.&nbsp;&nbsp;</p></li></ol><h2>Kernel (EL-1)&nbsp;</h2><p>The Android kernel manages these user space programs. Gaining kernel privilege can allow access to lower execution levels and the ability to perform sensitive actions, such as spying on phone calls and stealing your bitcoins.&nbsp;&nbsp;</p><h2>Hypervisor (EL-2)&nbsp;</h2><p>Qualcomm operates a hypervisor at EL-2, with the Android system as a monitored virtual machine. More virtual machines can be launched via an agent service on Android, found at <code>/product/etc/init/qvirtmgr.rc</code>.&nbsp;</p><pre><code># Qualcomm Virtualization Manager&nbsp;
service vendor.qvirtmgr /product/bin/qvirtmgr&nbsp;
&nbsp;&nbsp;&nbsp; class late_start&nbsp;
&nbsp;&nbsp;&nbsp; user root&nbsp;
&nbsp;&nbsp;&nbsp; group root&nbsp;
&nbsp;&nbsp;&nbsp; disabled&nbsp;
&nbsp;&nbsp;&nbsp; oneshot
</code></pre><h2>Trusted VM (EL-1)&nbsp;</h2><p>This service loads configurations from <code>/product/etc/qvirtmgr.json</code>.&nbsp;</p><pre><code>{ 
&#9;"qvirtmgr" : { 
&#9;&#9;"major_number": 1, 
&#9;&#9;&#9;"minor_number": 0, 
&#9;&#9;&#9;"vm_config" : [ 
&#9;&#9;&#9;{ 
&#9;&#9;&#9;&#9;"name"          : "trustedvm", 
&#9;&#9;&#9;&#9;"loader_type"   : "secured", 
&#9;&#9;&#9;&#9;"restart_level" : "relative", 
&#9;&#9;&#9;&#9;"try_count"     : 3, 
&#9;&#9;&#9;&#9;"boot_wait_time": 2, 
&#9;&#9;&#9;&#9;"boot_ops"      : "start", 
&#9;&#9;&#9;&#9;"disk" : [ 
&#9;&#9;&#9;&#9;{ "image"   : "/vendor/vm-system/trustedvm/system.img", "label" : 11 } 
&#9;&#9;&#9;&#9;], 
&#9;&#9;&#9;&#9;"enable"        : true, 
&#9;&#9;&#9;&#9;"legacy"        : true 
&#9;&#9;&#9;}, 
&#9;&#9;&#9;{ 
&#9;&#9;&#9;&#9;"name"          : "cpusys_vm", 
&#9;&#9;&#9;&#9;"loader_type"   : "secured", 
&#9;&#9;&#9;&#9;"restart_level" : "relative", 
&#9;&#9;&#9;&#9;"boot_wait_time": 2, 
&#9;&#9;&#9;&#9;"boot_ops"      : "start", 
&#9;&#9;&#9;&#9;"enable"        : true, 
&#9;&#9;&#9;&#9;"legacy"        : true 
&#9;&#9;&#9;} 
&#9;&#9;] 
&#9;} 
}
</code></pre><p>We can see a virtual machine &#8211; "trustedvm" &#8211; booting with a customized system image from <code>/vendor/vm-system/trustedvm/system.img</code>. This image is independent of the Android system image, and its execution is isolated from the Android world. An attacker with Android kernel privilege can't infiltrate the running trustedvm directly.&nbsp;</p><p>The trustedvm is dedicated to third-party programs by the vendor and for interaction functionality for the trusted UI. We found a program "tvmapploader" handling service requests from the normal world and delegating operations to the trusted apps inside the secure world.&nbsp;</p><p>Note that you don't need any vulnerability to gain kernel privilege on Android. If your device supports unlocking, you can flash your customized boot image onto your device, as we discussed in the previous blog.&nbsp;</p><p>However, communication from the normal world to the secure world is bridged through the trustedvm, making direct communication with the secure world challenging, you'll need another system image to interfere with the trustedvm. This is likely why <a href="https://www.youtube.com/watch?v=OUqEZS74hDk">hackers</a> don't directly attack the Seed Vault and demonstrate on a BTC wallet instead.&nbsp;&nbsp;</p><p>Despite all these measures, all parts of the normal world can be tampered with, potentially even in a fully patched Saga, if it's unlocked. So, the question is, If an attacker manages to gain root privilege through a backdoor on your phone, does this put the Seed Vault at risk? Let's investigate the design of Saga's secure world to find out.&nbsp;</p><h1>Demystifying the Seed Vault in the Secure World</h1><p>The trusted applications, <code>seedvault.mbn</code> and <code>argon2kdf.mbn</code>, are in the directory <code>/vendor/firmware_mnt/image/</code>, and they play crucial roles in Seed Vault's operations. (This research was conducted on the first released version of Solana's Saga smartphone, originally released as TKQ1.221220.242 in April 2023.)&nbsp;</p><p>These files are 64-bit arm64 ELF shared objects, stripped and unencrypted. This allows us to understand their low-level operations through reverse engineering.&nbsp;</p><h2>Decoding the Secure Storage</h2><p>The file <code>seedvault.mbn</code> is the core component of Seed Vault's secure storage system. It provides several interfaces:&nbsp;</p><pre><code>1.  SeedVault_generateSeedIndices&nbsp;    
2.  SeedVault_importSeedIndices&nbsp;    
3.  SeedVault_wipeSeed&nbsp;    
4.  SeedVault_signTransaction&nbsp;   
5.  SeedVault_authPublicKeys&nbsp;   
6.  SeedVault_changeSeedPassword&nbsp;    
7.  SeedVault_retrieveSeedIndices&nbsp;    
8.  SeedVault_verifyPassword&nbsp;    
9.  SeedVault_recoverSeed&nbsp;   
10.  SeedVault_enableBiometric&nbsp;    
11.  SeedVault_disableBiometric&nbsp;   
12.  SeedVault_getAttemptsLeft&nbsp;   
13.  SeedVault_getSeedInfo&nbsp;    
14.  SeedVault_getSeedSalt&nbsp;
</code></pre><p>These functions are straightforward and properly implemented.&nbsp;</p><p>Sensitive data is stored within the secure file system (sfs) provided by QSEE. The system can support up to 8 different seed vaults. The relationship between seeds and users is maintained in the <code>/seedvault_info</code> file. This file is structured as follows:&nbsp;</p><pre><code>struct seedvault_info {
&#9;struct {
&#9;&#9;uint64_t seed_id;
&#9;&#9;uint32_t user_id;
&#9;&#9;uint8_t flags;
&#9;} vaults[8];
};
</code></pre><p>Each seed is identified by a unique <code>seed_id</code> and is stored in a file named <code>/seedvault_${seed_id}</code>. The seed file is structured as follows:&nbsp;&nbsp;</p><pre><code>struct seed {
&#9;uint32_t version;
&#9;uint64_t seed_id;
&#9;uint32_t user_id;
&#9;uint8_t seed_salt[32];
&#9;uint8_t seed_key_nonce[12];
&#9;uint8_t seed_key_enc[32];
&#9;uint8_t seed_key_tag[16];
&#9;uint8_t salt[32];
&#9;uint8_t sha256_recovery_seed[32];
&#9;uint8_t seed_nonce[12];
&#9;uint8_t seed_enc[113];
&#9;uint8_t seed_tag[16];
&#9;uint8_t remaining_attempts;
};
</code></pre><h2>Limited Attempts Stop Guessing Attacks</h2><p>The seed never leaves the Trust Zone, and all operations related to the seed are executed within it. It's important to note that the seed is not stored in plain text, but instead, it's encrypted and always requires the correct password to access. Biometric authentication methods do not function until the seed is successfully accessed for the first time with the correct password.&nbsp;&nbsp;</p><p>If the password is unknown, there are only 10 attempts allowed to guess it. This is controlled by the <code>remaining_attempts</code> field in the securely stored seed. After 10 unsuccessful attempts, the seed is erased, your vault is gone forever!&nbsp;</p><p>The <code>seedvault.mbn</code> communicates exclusively with the trustedvm, which receives input passwords through a trusted UI. It's as if, during this process, the display and touchscreen are unplugged from the Android and reconnect to an invisible device. Therefore, even without explicit limitations, malicious programs cannot automate password guessing. Importantly, this process remains secure even in the face of a root privilege attack on the Android system, because the attacker cannot interfere with or simulate the interaction during the use of the trusted UI.&nbsp;&nbsp;&nbsp;</p><h2>Infeasibility of Offline Seed Cracking</h2><p>You may propose the following: could I not simply extract the seedvault files from the secure file system, potentially exploiting a vulnerability, and then brute force the password to recover the seed?&nbsp;</p><p>While theoretically possible, this approach comes with significant challenges. The seed is used, and its authenticity verified in two cases:&nbsp;</p><ol><li><p>Decrypting with the correct password.&nbsp;</p></li><li><p>Recovering with known mnemonic phrases.&nbsp;</p></li></ol><p>In the first case, the client in the Normal World, whether compromised or not, is required to employ a specialized algorithm to derive a <code>tz_password</code>, combining the guessed user password with a <code>seed_salt</code> that is queried from <code>seedvault.mbn</code>.&nbsp;</p><p>Remember trusted app <code>argon2kdf.mbn</code>? argon2 is a key derivation function designed to resist GPU cracking attacks (argon2i) or side-channel attacks (argon2d). The Seed Vault password uses the hybrid version <a href="https://http//4.%09https/cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id">argon2id</a> with enhanced parameters (iterations=8, memory size = 256KB), significantly amplifying the difficulty of brute-force attacks.&nbsp;&nbsp;</p><p>The second scenario is less likely to be attacked. It&#8217;s a mechanism to whether a newly recovered seed from the mnemonic phrases corresponds to the old one. The plaintext of the original seed is never stored in the file system. Instead, the SHA-256 hash of the initial seed, combined with a random 32-byte salt, is preserved. The validation can only be passed if you are aware of the true mnemonic phrase!&nbsp;</p><p>In conclusion, it&#8217;s just impossible to hack your seed vault if you use a strong password! This remains true even if your phone is physically hacked via a true bootloader vulnerability!&nbsp;</p><h1>Conclusion</h1><p>The crypto community has witnessed the emergence of numerous wallets, yet what truly matters is a wallet that can be implicitly trusted while remaining uncompromised. Through trust computing isolation and fortified key storage, Saga has set a high benchmark for mobile cryptocurrency security. While no system is completely invulnerable, Saga's approach has drastically minimized potential points of attack.&nbsp;&nbsp;</p><p>As we continue to delve into this rapidly evolving landscape, our focus remains on identifying potential vulnerabilities and enhancing security. It is our hope that more wallet providers will rise to the challenge, offering innovative solutions that match, if not exceed, the trustworthiness and safety Saga has showcased. &#129761;&nbsp;</p><h1>About Offside Labs</h1><p>Offside Labs is a professional team specializing in security research and vulnerability detection. Our primary focus includes rigorous bug hunting, comprehensive audits, and expert security consultation. We have extensive experience in the web3 environment and strive to enhance the security posture of our client's projects in this rapidly evolving digital space.&nbsp;</p><h1>References</h1><ol><li><p><a href="https://offside.io/blog/saga-of-saga-part-1-unlocking-the-debate-on-true-vulnerabilities">https://offside.io/blog/saga-of-saga-part-1-unlocking-the-debate-on-true-vulnerabilities</a>&nbsp;&nbsp;</p></li><li><p><a href="https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java;l=147-153">https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java;l=147-153</a>&nbsp;</p></li><li><p>Securing Web3 Mobile Wallets with TEE: Delving into the Security Guarantees and Real-world Implementation Pitfalls, Yuan Zhuang @ Certik, MOSEC 2023&nbsp;</p></li><li><p><a href="https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/How-5G-is-enabling-resilient-communication.pdf">https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/How-5G-is-enabling-resilient-communication.pdf</a>&nbsp;</p></li><li><p><a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id">https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id</a>&nbsp;</p></li><li><p><a href="https://slope-finance.medium.com/slope-wallet-sentry-vulnerability-digital-forensics-and-incident-response-report-d7a5904e5a39">https://slope-finance.medium.com/slope-wallet-sentry-vulnerability-digital-forensics-and-incident-response-report-d7a5904e5a39</a></p></li><li><p><a href="https://csrc.nist.gov/pubs/fips/186-5/final">https://csrc.nist.gov/pubs/fips/186-5/final</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[From Near Loss to Victory: The $2M Blockchain Rescue ]]></title><description><![CDATA[The Affine DeFi crisis averted: Our whitehat team stepped in, preventing a $2M theft and ensuring user funds' safety.]]></description><link>https://blog.offside.io/p/from-near-loss-to-victory-the-2m-rescue</link><guid isPermaLink="false">https://blog.offside.io/p/from-near-loss-to-victory-the-2m-rescue</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Tue, 12 Dec 2023 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e3ad574b-8e90-4f66-842f-e72172270ed5_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Our team recently encountered an emergency where $2M was at risk, and we immediately mobilized to secure the assets. This post-mortem analysis shares our journey, the challenges we faced, and the steps we took to safeguard funds from further exploitation.&nbsp;</p><h1>Alert! Unusual Transactions&nbsp;</h1><p>On December 8th, at 12:24 AM UTC, our monitoring system detected a malicious <a href="https://polygonscan.com/tx/0xba871ee415696243aa76fcca796486cadfc5bd893cf4258b42fbeabb97874843">transaction</a> on Polygon, where a hacker transferred out approximately $140k worth of USDC from the smart contract <code>0x829363736a5a9080e05549db6d1271f070a7e224</code>.&nbsp;</p><p>Later that same day, at 2:53 PM UTC, the same contract triggered our alarms again, this time for a significant <a href="https://polygonscan.com/tx/0x7acdeccba306b5b68c9f3a9a334cae66f039bf202cd865d00018c16d09612f41">influx</a> of assets into the vault.&nbsp;</p><p>The unusual signal caught our attention. The incoming sum was close to what had been stolen earlier. Could the hacker have just returned the stolen assets? We took a closer look at the smart contract. The first transaction seemed to be an attack related to the forwarded multicall&#8212;a novel vulnerability <a href="https://twitter.com/thirdweb/status/1731841493407576247">ThirdWeb</a> had only recently disclosed. We have observed numerous similar attacks on-chain. The stolen funds had been swapped to ETH and bridged to Ethereum.&nbsp;</p><h1>Code Red: The Race to Safeguard the Vault&nbsp;</h1><p>The incoming USDC was not from the attacker. There were a few users continuing to deposit into the vault. It became clear that the DeFi project associated with the vault was still active; the owner and users seemed oblivious to the breach. &nbsp;&nbsp;</p><p>The spider-sense of a hacker warned us something bad might happen again. Around $124K USDC was still at high risk, and we suspected that other predators in the &#8216;dark forest&#8217; might be on the prowl. We had to take immediate action to prevent any black hat hackers from seizing the funds!&nbsp;&nbsp;</p><p>However, what we knew about the vault was limited to only the source code of its smart contract and some addresses that had interacted with it. We didn&#8217;t know anything about the project behind the vault! &nbsp;Identifying and alerting the responsible team discreetly and promptly, without compromising the endangered assets, was a complex task. We were left with two options: fix the flaw or extract the funds before it was too late.&nbsp;</p><h1>Failed Attempts to Mitigate the Bug&nbsp;</h1><p>Based on our understanding of the root cause of the vulnerability, we knew there was a trusted forwarder in the vulnerable vault that could allow someone to counterfeit the <code>msgSender()</code> of internal transactions. &nbsp;For those interested, you can delve deeper into this type of bug.&nbsp;</p><ul><li><p><a href="https://blog.openzeppelin.com/arbitrary-address-spoofing-vulnerability-erc2771context-multicall-public-disclosure">Vulnerability Disclosure from OpenZeppelin</a></p></li><li><p><a href="https://dedaub.com/blog/critical-thirdweb-vulnerability">Vulnerability Analysis from Dedaub</a></p></li></ul><p>&nbsp;An effective mitigation of this bug is to disable the trusted forwarder. The function <code>setTrustedForwarder(address)</code> was designed for this purpose. It requires the caller to be a specific governance address, but we could manipulate the caller identity!&nbsp;</p><p>Our plan was to leverage the bug to set the TrustedForwarder to a null address. We spent some time debugging based on this idea. yet, we missed a critical detail: the <code>onlyGovernance()</code> modifier didn&#8217;t rely on the compromised <code>_msgSender()</code>; instead, it validated using <code>msg.sender</code> directly.&nbsp;</p><h1>Replaying the Exploit of the Original Hacker&nbsp;&nbsp;</h1><p>Our initial misdirection cost us time, but fortunately, the funds remained untouched. Another hack could happen at any time! We decided to preemptively execute a white-hat hack to rescue the funds. This meant exploiting the very same bug to preempt any malicious attempts, an approach that's unconventional in the real world, but very common in the web3 world, where swift action is often crucial and self-reliance is key.&nbsp;</p><p>The most effective strategy is to replicate the original hacker&#8217;s transaction. Because the nonce of the signed inner transaction from the initial breach is not reusable, we have to replace the hacker&#8217;s address to our own and craft new signatures for the embedded transactions.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5e5P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5e5P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 424w, https://substackcdn.com/image/fetch/$s_!5e5P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 848w, https://substackcdn.com/image/fetch/$s_!5e5P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 1272w, https://substackcdn.com/image/fetch/$s_!5e5P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5e5P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png" width="1100" height="392" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:392,&quot;width&quot;:1100,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!5e5P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 424w, https://substackcdn.com/image/fetch/$s_!5e5P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 848w, https://substackcdn.com/image/fetch/$s_!5e5P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.png 1272w, https://substackcdn.com/image/fetch/$s_!5e5P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe774dacf-ddf5-417a-95f2-a5e75982e87a_1100x392.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><h1>Bypassing the Ineffective Mitigation&nbsp;</h1><p>We quickly tested and deployed our exploit code, however, it didn&#8217;t work on-chain! &nbsp;Had the funds already been moved?&nbsp;It was then we noticed this <a href="https://polygonscan.com/tx/0x3554c7b169cf8ad37b2f670fe60580df4d2f8356fa6b359de66c905e43e9cee5">transaction</a>: &nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q5DW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q5DW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 424w, https://substackcdn.com/image/fetch/$s_!q5DW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 848w, https://substackcdn.com/image/fetch/$s_!q5DW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 1272w, https://substackcdn.com/image/fetch/$s_!q5DW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q5DW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png" width="1416" height="374" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:374,&quot;width&quot;:1416,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!q5DW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 424w, https://substackcdn.com/image/fetch/$s_!q5DW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 848w, https://substackcdn.com/image/fetch/$s_!q5DW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.png 1272w, https://substackcdn.com/image/fetch/$s_!q5DW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26971315-5018-4239-94e0-43fe8c85cadd_1416x374.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>Someone had paused the project! No further deposits or withdrawals could be made from the vault. It&#8217;s triggered from an address with the &#8220;Guardian&#8221; role. Great! The project owner was now clearly aware and responding to the emergency!&nbsp;</p><p>But did a pause mean secure? We didn't think pausing is a legit fix of the bug. Because the attacker can impersonate any user, including the &#8220;Guardian&#8221;, and simply unpause the project.&nbsp;</p><p>The potential workaround of the mitigation is pretty straightforward. The original hacker might have had a deeper understanding of the project's workings than us, but we had the advantage of speed. Rapidly, we deployed a refined exploit that included an unpause command, allowing us to resume operations and move all the at-risk funds to our secure vault. Finally relieved!&nbsp;</p><h1>Onchain Guidance&nbsp;</h1><p>We didn&#8217;t know who the owner of the vault was, but he must be desperate. So, we tried to deliver messages to him.&nbsp;</p><p>We published a <a href="https://polygonscan.com/tx/0x9b2f8e2b6ad5357c32a347d943b683050978d4a1bc31f6e75950e9cea3ed8435">message</a> to ourselves, stating:&nbsp;</p><blockquote><p>Don't worry, we are white-hat hackers. We will return the fund.&nbsp;</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ttz7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ttz7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 424w, https://substackcdn.com/image/fetch/$s_!ttz7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 848w, https://substackcdn.com/image/fetch/$s_!ttz7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 1272w, https://substackcdn.com/image/fetch/$s_!ttz7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ttz7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png" width="1456" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ttz7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 424w, https://substackcdn.com/image/fetch/$s_!ttz7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 848w, https://substackcdn.com/image/fetch/$s_!ttz7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.png 1272w, https://substackcdn.com/image/fetch/$s_!ttz7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf44e035-1a0c-4972-afa5-1ffcd9b7f04e_1600x407.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>We sent a <a href="https://polygonscan.com/tx/0x314ac549a83ff397f13606cdd54493279bfa280f9c3a6268f8b902401d1b0747">message</a> to the Governance address, teaching the owner the correct patch of the bug:&nbsp;</p><blockquote><p>Where should we return the funds to? First, you should disable the forwarder by 'setTrustedForwarder(0)'&nbsp;</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mQO8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mQO8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 424w, https://substackcdn.com/image/fetch/$s_!mQO8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 848w, https://substackcdn.com/image/fetch/$s_!mQO8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 1272w, https://substackcdn.com/image/fetch/$s_!mQO8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mQO8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png" width="1456" height="327" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:327,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mQO8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 424w, https://substackcdn.com/image/fetch/$s_!mQO8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 848w, https://substackcdn.com/image/fetch/$s_!mQO8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 1272w, https://substackcdn.com/image/fetch/$s_!mQO8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3543832b-4e47-42a6-a671-aa3f93473f50_1600x359.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Remarkably, within 10 minutes, the Governance executed a <a href="https://polygonscan.com/tx/0x18bcad18c169d26dd0f8afdef01210771a879fe2b756273d21d003c485d251d2">transaction</a> to reconfigure the trusted forwarder to itself.</p><p>Finally, the bug is patched! We have time to delve further&nbsp;into the source code while waiting for responses from the governance.&nbsp;</p><h1>Digging Beyond the Surface&nbsp;</h1><p>Let&#8217;s check the huge <a href="https://polygonscan.com/tx/0x7acdeccba306b5b68c9f3a9a334cae66f039bf202cd865d00018c16d09612f41">inflow</a> of $124k USDC first. Where was it from?&nbsp;</p><p>It&#8217;s processed by L2WormholeRouter and L2BridgeEscrow. Some components of this project are on another chain. The funds we transferred were just a portion of its TVL.&nbsp;</p><p>We got some clues from the wormhole router contract. By searching the keywords L1_FUND_TRANSFER_REPORT, we tracked down to a DeFi project <code>Affine</code>.&nbsp;</p><p>Gradually, we pieced together Affine's architecture:&nbsp;&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!24_k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!24_k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 424w, https://substackcdn.com/image/fetch/$s_!24_k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 848w, https://substackcdn.com/image/fetch/$s_!24_k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 1272w, https://substackcdn.com/image/fetch/$s_!24_k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!24_k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png" width="1456" height="1183" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1183,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!24_k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 424w, https://substackcdn.com/image/fetch/$s_!24_k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 848w, https://substackcdn.com/image/fetch/$s_!24_k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.png 1272w, https://substackcdn.com/image/fetch/$s_!24_k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1655c7db-65a0-4557-beb2-59805db77b71_1600x1300.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>Affine is a cross chain yield aggregator. It pools <a href="https://polygonscan.com/tx/0x81bd43aaa553afb183dfcb70909b92593d7a70d435e44809be3ecdd32ad3b88f">deposits</a> on L2 (Polygon) and sends funds to L1 (Ethereum), maintaining an investment ratio of 47:3. &nbsp;</p><p>Since the manager on L2 has no direct knowledge of L1 status, a bot with the role &#8220;Harvester&#8221; is scheduled to synchronize the two layers via the wormhole network.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aZXP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aZXP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 424w, https://substackcdn.com/image/fetch/$s_!aZXP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 848w, https://substackcdn.com/image/fetch/$s_!aZXP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 1272w, https://substackcdn.com/image/fetch/$s_!aZXP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aZXP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png" width="1140" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1140,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!aZXP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 424w, https://substackcdn.com/image/fetch/$s_!aZXP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 848w, https://substackcdn.com/image/fetch/$s_!aZXP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.png 1272w, https://substackcdn.com/image/fetch/$s_!aZXP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a0406ad-5d08-4432-a33c-3e663b517f31_1140x562.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>Upon receiving updated TVL data from L1, L2 decides whether to rebalance the portfolio by either withdrawing from or sending extra funds to L1.&nbsp;&nbsp;</p><p>After the initial hacker draining the vault on L2, the portfolio of Affine is heavily imbalanced. Consequently, the bot initiated a rebalance, prompting L1 to send funds back to L2. With over $2M on L1, roughly $120k - 6% of TVL - was transferred due to this automation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qy5p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qy5p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 424w, https://substackcdn.com/image/fetch/$s_!Qy5p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 848w, https://substackcdn.com/image/fetch/$s_!Qy5p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 1272w, https://substackcdn.com/image/fetch/$s_!Qy5p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qy5p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png" width="1456" height="915" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:915,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Qy5p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 424w, https://substackcdn.com/image/fetch/$s_!Qy5p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 848w, https://substackcdn.com/image/fetch/$s_!Qy5p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.png 1272w, https://substackcdn.com/image/fetch/$s_!Qy5p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e55f113-d060-4cbd-b47f-ce9fe522c4f1_1600x1006.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>Could we initiate a rebalance by ourselves? The rebalance is only triggered by a public function <code>receiveTVL()</code> in L2Vault, which requires the <code>_msgSender()</code> to be the L2WormholeRouter. Given the exploitability of <code>_msgSender()</code>, the hacker could have forced the L2 to rebalance and request the L1 to move all the 2M funds back to L2!&nbsp;</p><p>We were really surprised that <strong>our intervention had safeguarded not merely $110k but $2M!</strong></p><p>Meanwhile, we realized what we and the hacker had done in the exploit. We had burned and withdrawn shares on behalf of a major Liquidity Provider (LP) in the pool. The exploit had not affected others. With this insight, it became evident that we needed to return the funds to the LP's address.&nbsp;</p><h1>Closing&nbsp;</h1><p>Despite the absence of an on-chain response, we had identified the project's owner. We took to Twitter, broadcasting our findings and tagging <a href="https://twitter.com/AffineDeFi">@AffineDefi</a> in our post:</p><p>Upon their confirmation of the LP's address, we promptly <a href="https://polygonscan.com/tx/0x29def310fe3c1512656c0e370f45a18f7f4ba3878755bf8eddfee862aa822c3b.">returned</a> the funds.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XuGK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XuGK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 424w, https://substackcdn.com/image/fetch/$s_!XuGK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 848w, https://substackcdn.com/image/fetch/$s_!XuGK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 1272w, https://substackcdn.com/image/fetch/$s_!XuGK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XuGK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png" width="1456" height="758" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:758,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!XuGK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 424w, https://substackcdn.com/image/fetch/$s_!XuGK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 848w, https://substackcdn.com/image/fetch/$s_!XuGK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.png 1272w, https://substackcdn.com/image/fetch/$s_!XuGK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42bb7ee6-fd19-4d59-8c14-ce2cb70562a2_1600x833.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>As a result, we were awarded with a $10k bounty for the white-hat hack.&nbsp;</p><p>With the funds now secure and the vulnerability patched, our work comes to a close. But our mission is not over. We stand ready to confront emerging challenges, ever committed to safeguarding the integrity of the blockchain ecosystem.&nbsp;</p><h1>Timeline&nbsp;</h1><ul><li><p>2023-12-08 00:24 UTC - First attack detected.&nbsp;</p></li><li><p>2023-12-08 14:53 UTC - Alerted to a large influx of funds.&nbsp;</p></li><li><p>2023-12-08 15:30 UTC - Initiated an investigation into the unusual activity.&nbsp;</p></li><li><p>2023-12-08 16:40 UTC - Transferred funds to our secure vault for protection.&nbsp;</p></li><li><p>2023-12-08 17:09 UTC - Disclosed our status as white-hat hackers.&nbsp;</p></li><li><p>2023-12-08 17:20 UTC - Sent on-chain messages to the project owner.&nbsp;</p></li><li><p>2023-12-08 19:54 UTC - Posted a tweet requesting direct messaging with Affine DeFi.&nbsp;</p></li><li><p>2023-12-08 20:03 UTC - Affine DeFi reached out to us on Twitter.&nbsp;</p></li><li><p>2023-12-08 20:21 UTC - Detailed our actions in securing $110k USDC.&nbsp;</p></li><li><p>2023-12-08 22:24 UTC - Affine DeFi confirmed the plan for a public recovery.&nbsp;</p></li><li><p>2023-12-08 22:34 UTC - Returned the funds to the user.&nbsp;</p></li><li><p>2023-12-08 23:10 UTC - Received a bounty from Affine DeFi for our white-hat hacking efforts.&nbsp;</p></li></ul>]]></content:encoded></item><item><title><![CDATA[Saga of Saga - Part 1: Unlocking the Debate on True Vulnerabilities]]></title><description><![CDATA[If a victim has to give his password, erase his phone, and hand it over, is it still a vulnerability? Dive into our analysis of the Saga mobile's security debate, as we scrutinize Certik's vulnerability claims and examine Saga's bootloader unlocking process.]]></description><link>https://blog.offside.io/p/saga-of-saga-part-1-unlocking-the-debate</link><guid isPermaLink="false">https://blog.offside.io/p/saga-of-saga-part-1-unlocking-the-debate</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Sun, 26 Nov 2023 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/cccd6771-e582-4746-80ac-4afc643e71c2_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Introduction&nbsp;</h1><p>There's been a recent debate between the Solana Mobile team and Certik, a security firm, about the security of the Saga, Solana's own mobile phone. As a leading group in web3 security with extensive experience in mobile security, we're here to offer our insights on this matter.&nbsp;</p><p>In this blog post, you'll get a clearer picture of Saga's security design and understand why this premium crypto hardware might be a good (or not so good) investment for you. Let's delve into the Saga debate!&nbsp;</p><h1>The Saga Security Controversy&nbsp;</h1><p>Certik dropped a demo on how to steal from a BTC wallet on a web3 phone, the Solana Saga. They claimed they'd "revealed a significant bootloader vulnerability in the Solana Phone", which presents "a challenge not just for this device, but for the entire industry".&nbsp;</p><p>This claim sparked a lot of chatter. But wait a minute, in the warm-up video for their demo, they're not chatting about any 'vulnerabilities' here, they're actually showing folks how to 'backdoor your phone'. Based on the content of Certik's latest demo, one could infer that they have installed backdoored firmware on their Saga, a process that required unlocking the bootloader.&nbsp;</p><p>So, you might be scratching your head, &#8220;What on earth is 'unlocking the bootloader'?&#8221; Well, it's a handy optional feature that vendors offer, allowing you to install custom firmware. You'll find it in many Android devices, the Google Pixel included.&nbsp;</p><p>The Solana Mobile team refuted the claim of the so-called vulnerability on their Discord, stating:&nbsp;</p><blockquote><p>The video shows the user unlocking the bootloader, which is something that can be done on many Android devices (as outlined in Android Open Source Project&#8217;s documentation). Additionally, unlocking the bootloader is an advanced feature of Saga which requires multiple explicit steps, and is disabled by default.</p></blockquote><h1>Verifying the Unlocking Process&nbsp;</h1><p>Following the buzz around Certik's demo and Solana Mobile team's rebuttal, we decided to verify the bootloader unlocking process ourselves. We've expanded on the key insights initially shared on our Twitter thread for a more comprehensive understanding.&nbsp;</p><h2>Insight 1: Standard Security Measures&nbsp;</h2><p>The first key insight from our investigation is that the Solana Phone, like many other mainstream devices including Google Pixel, is locked by default. This is a common security measure implemented by manufacturers to protect user data right out of the box.&nbsp;</p><h2>Insight 2: Unlocking Process&nbsp;</h2><p>Unlocking the Saga involves a two-step process. First, enabling developer mode, OEM unlocking, and USB debugging on the phone&#8212;actions that require your passcode. The second step requires connecting the phone to a laptop via USB, rebooting to the bootloader, and entering a specific command (<code>fastboot flash unlocking_critical</code>) into the laptop's console.&nbsp;</p><p>This insight shows that unlocking the device requires a certain level of technical expertise and intentional actions, rather than being something that could happen accidentally.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;5d38598f-428c-4fb8-9d8d-8c63d8631779&quot;,&quot;duration&quot;:null}"></div><h2>Insight 3: Data Wipe After Unlocking&nbsp;</h2><p>A noteworthy observation is that once the Saga is unlocked, it automatically wipes all previous storage and credentials, including the "Seed Vault" &#8212; a core feature of Saga that we'll expand on later. The unlocking process functions like a comprehensive reset button, erasing all prior data.&nbsp;</p><p>A final warning is also displayed to the user, outlining the risks and consequences of proceeding with the unlocking. This observation underscores the irreversible nature of unlocking and the serious data privacy considerations involved, especially in relation to the "Seed Vault" feature.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ukU0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ukU0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ukU0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ukU0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ukU0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ukU0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg" width="346" height="680" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:680,&quot;width&quot;:346,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;final warning&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="final warning" title="final warning" srcset="https://substackcdn.com/image/fetch/$s_!ukU0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ukU0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ukU0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ukU0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F160e592c-c66d-4428-8170-07be646b0bef_346x680.jpeg 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><h2>Insight 4: Unmissable Alert</h2><p>Lastly, unlocking the Saga does not go unnoticed. An unlocked phone triggers a clear and lengthy alert every time the device is booted up. This persistent alert serves as a constant reminder of the altered security state of the device. This insight emphasizes that while the unlocking feature is available, it is not treated lightly by the system or hidden from the user.&nbsp;</p><p>In conclusion, these insights demonstrate that while bootloader unlocking is indeed possible on the Saga, it is designed as an advanced feature with numerous safeguards and warnings, rather than a vulnerability.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;c81fe8ac-50c8-4e07-acff-709ce19978a7&quot;,&quot;duration&quot;:null}"></div><h1>What Constitutes a Genuine Bootloader Vulnerability?&nbsp;</h1><p>An unlocked bootloader allows you to run a customized mobile operating system. However, this is not necessarily a vulnerability. A bootloader becomes a vulnerability if it can be unlocked without following the established rules.&nbsp;</p><p>For instance, it would be considered a vulnerability if it can be unlocked even when the vendor has intentionally disabled this functionality. Similarly, it would be a vulnerability if the bootloader could be unlocked without user authorization, or if unlocking it doesn't erase user data. Lastly, it's a vulnerability if the system can boot without displaying permanent warnings after unlocking.&nbsp;</p><p>In fact, there have been numerous notable bootloader vulnerabilities throughout history. Almost every popular hardware device, regardless of its price, has experienced hacks exploiting bootloader vulnerabilities. This includes devices from <a href="https://www.wired.com/story/ios-exploit-jailbreak-iphone-ipad/">Apple</a>, <a href="https://www.blackhat.com/us-20/briefings/schedule/index.html#breaking-samsungs-root-of-trust-exploiting-samsung-s-secure-boot-20290">Samsung</a>, <a href="https://media.defcon.org/DEF%20CON%2029/DEF%20CON%2029%20presentations/Christopher%20Wade%20-%20Breaking%20Secure%20Bootloaders.pdf">Qualcomm</a>, <a href="https://github.com/amonet-kamakiri/kamakiri/">MediaTek</a>, <a href="https://labs.taszk.io/blog/post/bootrom_usb/">Huawei</a>, <a href="https://github.com/SKGleba/broombroom">Sony</a>, and even <a href="https://misc.ktemkin.com/fusee_gelee_nvidia.pdf">Nintendo</a>. We have seen many talented hackers discover new vulnerabilities in bootloaders, but none of them would agree that simply enabling unlocking constitutes a bug.&nbsp;&nbsp;</p><p>That's why we firmly believe that Certik must have noticed something unusual inside Saga's bootloader. Otherwise, they could have simply demonstrated an attack against Google Pixel and claimed that its 30 million users were under threat of losing their bitcoins.&nbsp;</p><p>So, our exploration into the depths of Saga's complexities continues. Next up, we'll tackle Saga's security design and implementation. Stay tuned for "Saga of Saga - Part 2".&nbsp;</p>]]></content:encoded></item><item><title><![CDATA[Unrolling the Scroll: Probing the Security of a Zero-Knowledge Roll-Up ]]></title><description><![CDATA[Dive into our quest to uncover vulnerabilities in Scroll's zero-knowledge roll-up, exposing subtle bugs and exploring the security measures within this exciting frontier of zk-rollups and web3.]]></description><link>https://blog.offside.io/p/unrolling-the-scroll</link><guid isPermaLink="false">https://blog.offside.io/p/unrolling-the-scroll</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Sun, 12 Nov 2023 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/06a3021c-001c-48f5-a606-835b0d928aea_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Introduction&nbsp;</h1><p>A few months back, our group stumbled upon an early bug bounty program hosted by Scroll, an up-and-coming zero-knowledge roll-up. They were offering big money - $5,000 each - for finding buggy transactions in their testnet.&nbsp;</p><p>As skilled hackers always on the lookout for new frontiers, the pre-launch bug bounty from Scroll immediately piqued our interest. The <a href="https://hackmd.io/@iczc/scroll-prover-bug-bounty">announcement</a> landed squarely on our radar for hunting down vulnerabilities!&nbsp;</p><p>We went into hacking Scroll with zero knowledge about their clever zero-knowledge roll-up setup. By fuzzing their code and tweaking things, we found something interesting. It gave us a glimpse into how seriously they take security.&nbsp;</p><p>In this blog post, we will not only narrate our exciting hacking journey but also share our observations and insights about the security measures employed by Scroll.&nbsp;</p><h1>Scroll: A Security-focused Scaling Solution for Ethereum&nbsp;</h1><p><a href="https://scroll.io/">Scroll</a> is a zkRollup Layer 2 dedicated to enhancing Ethereum scalability through a bytecode-equivalent zkEVM circuit. The mainnet of Scroll was <a href="https://twitter.com/Scroll_ZKP/status/1714267555307950451">launched</a> last month.&nbsp;</p><p>Scroll is composed of three layers: settlement layer, sequencing layer and proving layer.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eHcc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eHcc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 424w, https://substackcdn.com/image/fetch/$s_!eHcc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 848w, https://substackcdn.com/image/fetch/$s_!eHcc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 1272w, https://substackcdn.com/image/fetch/$s_!eHcc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eHcc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;layers&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="layers" title="layers" srcset="https://substackcdn.com/image/fetch/$s_!eHcc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 424w, https://substackcdn.com/image/fetch/$s_!eHcc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 848w, https://substackcdn.com/image/fetch/$s_!eHcc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 1272w, https://substackcdn.com/image/fetch/$s_!eHcc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F242d38b1-2d9a-4f1d-b9f7-9799f97b0b79_2640x1320.webp 1456w" sizes="100vw" fetchpriority="high"></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>The settlement layer refers to smart contracts deployed on the Ethereum network, where the roll-up submits and verifies the validity of computations conducted in the nested layer. The sequencing layer forms the major user-facing component as an isolated yet fully EVM-compatible chain.&nbsp;</p><p>Together, these two layers make up the typical architecture found in alternative layer 2 public blockchain solutions, with the settlement layer confirming operations from the standalone sequencing environment.&nbsp;</p><p>The proving layer differentiates zero-knowledge rollups from traditional implementations, representing an additional component. The most captivating advantage conferred by zk techniques is the rollup's ability to give a succinct proof of the entire layer 2 chain state without broadcasting individual transactions to Ethereum, thus ensuring time and space efficiency.&nbsp;</p><p>However, generating these proofs demands non-trivial computational overhead beyond the capabilities of regular execution nodes. So, Scroll set up a layer just for intensive computation work. The proving tasks are handled by super powerful nodes or distribution across a group of such nodes. The specialized proving layer focuses only on that, keeping layer 2 running without proofing's steep resource costs slowing it down.&nbsp;</p><h1>The Rolling-up Scroll: Execution, Commitment and Finalization&nbsp;</h1><p>The <a href="https://docs.scroll.io/en/technology/chain/rollup/">rollup process</a> can be broken down into three phases:</p><ol><li><p>Transaction Execution&nbsp;</p></li><li><p>Batching and Data Commitment&nbsp;</p></li><li><p>Proof Generation and Finalization&nbsp;</p></li></ol><p>The first two layers function asynchronously yet cohesively irrespective of the additional computation in the proving layer. However, unavoidable lags from proving labor could potentially induce inconsistency between the two layers.&nbsp;&nbsp;</p><p>Consider this scenario: A valid transaction is confirmed by the sequencing layer (L2Geth), and the settlement layer records the commitment with its batch details. However, the proving layer cannot craft a proof for it! Only after extensive GPU hours does the prover realize they are unable to generate a valid witness, or the proof does not match what is needed.&nbsp;&nbsp;</p><p>It is important to note that this concept differs from chain reorg issues seen in other alternative chains. Typically, reorg problems in those systems are caused by networking difficulties among interconnected nodes. The current version of Scroll is running in a controlled (centralized) manner. Reorgs in other networks would happen and resolve silently by design. However, the proving failures may not be straightforward for Scroll.&nbsp;</p><p>If a transaction is unprovable, it stops the full batch from finalizing. This blocks the whole network. Now you could revert any transactions after the toxic one and remove it and related transactions, like a hard fork. Or you could manually add fake proofs just for these cases. But that second option would go against the purpose of the roll-up system by adding unproven transactions.&nbsp;&nbsp;</p><p>It is a tricky situation that requires carefully considering options like forks or alternate proofs to resolve inconsistencies without compromising integrity. Handling troublesome transactions in a safe way is exactly what the Scroll team is worried about. That is why they set up a bug bounty program for this specific problem!&nbsp;</p><h1>Fuzzing the Bus Mapping: Unleashing Chaos in Search of Vulnerabilities&nbsp;</h1><p>There are some potential reasons that could cause prover bugs, as listed on the <a href="https://hackmd.io/@iczc/scroll-prover-bug-bounty#Possible-Reasons">bug bounty page</a>:&nbsp;</p><ol><li><p>Missing information in the generated trace.&nbsp;</p></li><li><p>Errors when the bus-mapping module processes traces from L2Geth.&nbsp;</p></li><li><p>Divergent behavior between L2Geth and the zkEVM circuit.&nbsp;</p></li><li><p>Bypassing the circuit capacity check.&nbsp;</p></li></ol><p>These bugs could appear in various parts of the Scroll project workflow:&nbsp;</p><ul><li><p>Transactions are validated and executed by L2Geth, which generates execution traces.&nbsp;</p></li><li><p>The bus-mapping module converts traces to a format for the zkEVM circuit.&nbsp;</p></li><li><p>The witness and zkEVM circuit generate the proof, requiring a match with L2Geth behavior.&nbsp;</p></li><li><p>A capacity checker is needed because zkEVM circuits have finite capability.&nbsp;</p></li></ul><p>The trace generator and circuit capacity checker are implemented in L2Geth. We manually reviewed the Golang code added by the Scroll team and the code seems well written.&nbsp;</p><p>As we did not have the budget to set up a powerful prover node capable of generating actual proofs, we decided to leave the bug hunting in zkEVM circuits as a challenge for moneyed hackers. (Conducting such proofs could require computational resources more expensive than the bounty rewards.)&nbsp;</p><p>This effectively ruled out targeting the circuits themselves. The only component remaining within our scope to audit was the bus-mapping module, as evaluating its code would not demand generating a full proof.&nbsp;&nbsp;</p><p>The bus mapping module is responsible for parsing transaction traces executed in L2Geth and converting them into the witness required to generate proofs.&nbsp;&nbsp;</p><p>In reviewing the bus mapping source code, we discovered that the project has comprehensive unit tests. With only minor modifications, we were able to construct a basic harness to execute the tests.&nbsp;</p><pre><code>use libfuzzer_sys::fuzz_target; 
... 
fuzz_target!(|data: &amp;[u8]| { 
    let code = Bytecode::from_raw_unchecked(data.into()); 
    // Get the execution steps from the external tracer 
    let block: GethData = TestContext::&lt;2, 1&gt;::new( 
        None, 
        account_0_code_account_1_no_code(code), 
        tx_from_1_to_0, 
        |block, _tx| block.number(0xcafeu64), 
    ) 
    .unwrap() 
    .into(); 
  
    let mut builder = BlockData::new_from_geth_data(block.clone()).new_circuit_input_builder(); 
    builder 
        .handle_block(&amp;block.eth_block, &amp;block.geth_traces); 
}); 
</code></pre><p>Within five minutes, we were able to trigger an interesting crash using cargo-fuzz. It generated corpus input with considerable complexity, yet the underlying crash seemed straightforward.&nbsp;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T7fA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T7fA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 424w, https://substackcdn.com/image/fetch/$s_!T7fA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 848w, https://substackcdn.com/image/fetch/$s_!T7fA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 1272w, https://substackcdn.com/image/fetch/$s_!T7fA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T7fA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png" width="1456" height="690" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:690,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;crashed&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="crashed" title="crashed" srcset="https://substackcdn.com/image/fetch/$s_!T7fA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 424w, https://substackcdn.com/image/fetch/$s_!T7fA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 848w, https://substackcdn.com/image/fetch/$s_!T7fA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.png 1272w, https://substackcdn.com/image/fetch/$s_!T7fA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47e8bea6-bf62-4e56-9c49-771f1dcd1095_3840x1820.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><h1>The Discovery: Unveiling a Subtle Bug in Scroll&nbsp;&nbsp;</h1><p>Specifically, the crash occurred within the get_create_init_code function when the offset_end variable exceeded memory boundaries during an access, resulting in a segmentation fault. Despite the complexity of the randomly generated fuzzing corpus, the crash proved easily reproducible and localized to a single out-of-bounds memory access.</p><pre><code>pub fn get_create_init_code&lt;'a&gt;( 
    call_ctx: &amp;'a CallContext, 
    step: &amp;GethExecStep, 
) -&gt; Result&lt;&amp;'a [u8], Error&gt; { 
    let offset = step.stack.nth_last(1)?.low_u64() as usize; 
    let length = step.stack.nth_last(2)?.as_usize();
 
    let mem_len = call_ctx.memory.0.len(); 
    if offset &gt;= mem_len { 
        return Ok(&amp;[]); 
    } 
 
    let offset_end = offset.checked_add(length).unwrap_or(mem_len); 
    Ok(&amp;call_ctx.memory.0[offset..offset_end]) 

} 
</code></pre><p>The vulnerable function can be triggered when calling the create2_address function.&nbsp;</p><pre><code>pub(crate) fn create2_address(&amp;self, step: &amp;GethExecStep) -&gt; Result&lt;Address, Error&gt; { 
    let salt = step.stack.nth_last(3)?; 
    let call_ctx = self.call_ctx()?; 
    let init_code = get_create_init_code(call_ctx, step)?.to_vec(); 
    let address = get_create2_address(self.call()?.address, salt.to_be_bytes(), init_code); 
    log::trace!( 
        "create2_address {:?}, from {:?}, salt {:?}", 
        address, 
        self.call()?.address, 
        salt 
    ); 
    Ok(address) 

} 
</code></pre><p>The CREATE2 opcode enables deterministic prediction of contract deployment addresses without actual deployment. The underlying idea is to make addresses independent of future blockchain events - a contract can always be deployed at its precomputed address regardless of what happens.&nbsp;</p><p>New contract addresses are a function of:&nbsp;</p><ol><li><p>0xFF, a constant that prevents collisions with regular CREATE&nbsp;</p></li><li><p>The sending account address&nbsp;</p></li><li><p>A salt value provided by the sender&nbsp;</p></li><li><p>The bytecode of the contract to be deployed&nbsp;</p></li></ol><p>The address is calculated as:&nbsp;</p><p><code>new_address = hash(0xFF, sender, salt, bytecode)&nbsp;</code></p><p>The calculation of the new address triggered the memory access violation bug by fetching the bytecode from an unallocated memory region.&nbsp;&nbsp;</p><p>We created a basic Proof of Concept (PoC) by invoking the CREATE2 instruction with specific parameters that were expected to exceed memory boundaries: value=0, offset=0, length=100, salt=0. Surprisingly, this did not result in a crash as expected.&nbsp;</p><p>Analyzing the crashing corpus revealed that the CREATE2 instruction had been executed twice. This raised concerns about potential issues in the logic handling conflict resolution when multiple create2 operations share the same salt.&nbsp;</p><p>Simply put, EVM does not allow multiple contracts to be created at the same address. The second creation will fail due to a contract address collision error. When parsing traces from L2Geth, the bus mapping module aims to analyze and understand the underlying causes of any encountered errors. If a CREATE2 instruction fails execution, it computes the cryptographic hash of the associated code to derive and track the duplicated contract address.&nbsp;</p><pre><code>if matches!(step.op, OpcodeId::CREATE | OpcodeId::CREATE2) { 
    let (address, contract_addr_collision_err) = match step.op { 
        OpcodeId::CREATE =&gt; ( 
            self.create_address()?, 
            ContractAddressCollisionError::Create, 
        ), 
        OpcodeId::CREATE2 =&gt; ( 
            self.create2_address(step)?, 
            ContractAddressCollisionError::Create2, 
        ), 
        _ =&gt; unreachable!(), 
    }; 
    let (found, _) = self.sdb.get_account(&amp;address); 
    if found { 
        log::debug!( 
            "create address collision at {:?}, step {:?}, next_step {:?}", 
            address, 
            step, 
            next_step 
        ); 
        return Ok(Some(ExecError::ContractAddressCollision( 
            contract_addr_collision_err, 
        ))); 
    } 
} 
</code></pre><p>Nothing goes wrong until memory expansion occurs. If an instruction dereferences a location beyond the current memory boundary, memory is automatically expanded and initialized with zeroes. This is handled correctly by L2Geth and bus mapping for the execution of every opcode.&nbsp;</p><p>However, memory expansion does not take place inside the error handler for failed executions. This is why the subtle bug can only be triggered during a contract address collision, when the failed create2 invocation does not cause an expansion of memory space before the address calculation dereferences outside the initialized region.&nbsp;</p><h1>The Circuit Capacity Checker: An Additional Layer of Defense&nbsp;</h1><p>We tried to launch the attack script against our local test node, but still nothing happened. We thought we were close to claiming the bug bounty, however, the Scroll team anticipated this one step ahead of us. It was the circuit capacity checker (CCC) that blocked the potential hacks.&nbsp;</p><p>The CCC, as you may remember, is designed to calculate the required circuit gates for a specific transaction and reject those considered too costly. The L2Geth node invokes CCC to simulate incoming transactions. Any bugs within the bus mapping module would also affect CCC. If CCC were to crash, the L2Geth node would simply drop the troublesome transaction rather than exposing a vulnerability.&nbsp;</p><p>The CCC provides extra protection as a firewall. It evaluates transaction costs before execution. This helps prevent unknown attacks from overloading resources or exploiting memory bugs through crashing. This auxiliary defense strengthens the overall security of the platform.&nbsp;</p><h1>Conclusion&nbsp;&nbsp;</h1><p>We reported our findings to the Scroll team, who then quickly deployed a <a href="https://github.com/scroll-tech/zkevm-circuits/pull/990/files">fix</a> for the memory corruption bug just before the launch of their mainnet. Our speed hacking attempts with Scroll did not yield a bounty. But we are glad we understood their rollup's robust security. The Scroll team clearly <a href="https://scroll.io/blog/scrolls-security-measures">did great work</a> fortifying it. Props to them!&nbsp;</p><p>While this hack did not pay off, we are excited by how much we learned dissecting their defenses. It inspired us to keep challenging ourselves with zk-rollups and web3. The possibilities are endless - our learning has just begun!&nbsp;</p><h1>About Offside Labs&nbsp;</h1><p>Offside Labs is a professional team specializing in security research and vulnerability detection. Our primary focus includes rigorous bug hunting, comprehensive audits, and expert security consultation. We have extensive experience in the web3 environment and strive to enhance the security posture of our client's projects in this rapidly evolving digital space.&nbsp;</p><h1>References&nbsp;</h1><ol><li><p><a href="https://github.com/scroll-tech/zkevm-circuits/blob/40f4758f5b4b5a5c82fb312ee58492487f181185/bus-mapping/src/circuit_input_builder/input_state_ref.rs#L1666-L1690">https://github.com/scroll-tech/zkevm-circuits/blob/40f4758f5b4b5a5c82fb312ee58492487f181185/bus-mapping/src/circuit_input_builder/input_state_ref.rs#L1666-L1690</a>&nbsp;</p></li><li><p><a href="https://github.com/scroll-tech/zkevm-circuits/blob/40f4758f5b4b5a5c82fb312ee58492487f181185/bus-mapping/src/circuit_input_builder/input_state_ref.rs#L909-L921">https://github.com/scroll-tech/zkevm-circuits/blob/40f4758f5b4b5a5c82fb312ee58492487f181185/bus-mapping/src/circuit_input_builder/input_state_ref.rs#L909-L921</a>&nbsp;</p></li></ol>]]></content:encoded></item><item><title><![CDATA[Could Wrapped Tokens Like WETH Be (forced) Insolvent?]]></title><description><![CDATA[Uncover the fascinating journey of a budding hacker delving into Interlay's Bitcoin-Polkadot bridge, interBTC, and revealing critical security flaws in its over-collateralization and fraud-proof systems.]]></description><link>https://blog.offside.io/p/could-wrapped-tokens-like-weth-be-insolvent</link><guid isPermaLink="false">https://blog.offside.io/p/could-wrapped-tokens-like-weth-be-insolvent</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Wed, 21 Dec 2022 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b1f93ed0-75dd-4eb6-8728-c8be127e9381_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>People are joking around the seeming depegging of WETH. The wrapped ETH token contract, the most simple and fundamental contract in the Ethereum ecosystem, is used in almost every DeFi protocol. If the depegging happens, the empire of Ethereum will collapse. Trust me, the depegging of WETH is the last thing you should worry about in Ethereum. Because when that happens, both your ETH and WETH would be worthless.</p><p>Will we see the doomsday of Ethereum? What if a catastrophic vulnerability is discovered and exploited in the Ethereum network? Considering the security model of Ethereum, I don&#8217;t think that could happen. The execution of smart contracts and the consensus of the network are implemented in multiple independent software clients, a single flaw or discrepancy that affects a minority of the clients will be discarded by the network. Even if we see a nuclear-level bug that destroys all the Ethereum nodes, the community can always fork a new secured chain as the canonical Ethereum, like we have done in <a href="https://ethereum.org/en/governance/#dao-fork">the DAO fork</a>.</p><p>However, not all EVM compatible chains are guarded at the same security level and with the same decentralization as Ethereum. In fact, most &#8220;Ethereum killer&#8221; chains only have one single implementation of their protocol. The lack of diversity is the Achilles&#8217; heel of public chains: if anything goes wrong in their official implementation, the giant will be knocked down easily.</p><p>A few months ago, I found a critical vulnerability in <a href="https://github.com/paritytech/frontier">paritytech/frontier</a>, an EVM implementation written in rust and mainly used in Polkadot parachains. When I was writing my <a href="https://pwning.mirror.xyz/okyEG4lahAuR81IMabYL5aUdvAsZ8cRCbYBXh8RHFuE">previous blog post</a>, I decided to take one more quick review of the code used in the Moonbeam network, in case I missed anything trivial but critical. My hacker instinct led me to a tricky integer truncation bug!</p><p>Frontier executes normal Ethereum smart contracts, but uses a Polkadot substrate as the ledger. This has a quirk: while balance amounts are 256 bit integers in normal Ethereum, the currency in the Polkadot substrate is only 128 bit. To convert to Polkadot, frontier truncates the 256 bit transfer balance amount to 128 bits. This is the code that handles value transferring in the frontier EVM:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oWVv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oWVv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 424w, https://substackcdn.com/image/fetch/$s_!oWVv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 848w, https://substackcdn.com/image/fetch/$s_!oWVv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 1272w, https://substackcdn.com/image/fetch/$s_!oWVv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oWVv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png" width="1023" height="408" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:408,&quot;width&quot;:1023,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;frontier/frame/evm/src/runner/stack.rs&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="frontier/frame/evm/src/runner/stack.rs" title="frontier/frame/evm/src/runner/stack.rs" srcset="https://substackcdn.com/image/fetch/$s_!oWVv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 424w, https://substackcdn.com/image/fetch/$s_!oWVv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 848w, https://substackcdn.com/image/fetch/$s_!oWVv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 1272w, https://substackcdn.com/image/fetch/$s_!oWVv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ba1dabe-c1d7-4e18-bbbb-3398bce9fb22_1023x408.png 1456w" sizes="100vw" fetchpriority="high"></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>Since the balance can never be greater than 128 bit, and the transfer will be validated by the balance substrate eventually, what could go wrong?</p><p>The key is that the <code>transfer.value</code> here, or <code>msg.value</code> in EVM, is a totally controlled 256 bit value provided by the user. If we pass (1 &lt;&lt; 128) in the <code>msg.value</code>, <code>T::Currency::transfer</code> will do nothing because it&#8217;s transferring a truncated zero, and we&#8217;ll finish the EVM execution smoothly. We won&#8217;t get any extra balance by transferring the zero, but what if the giant untruncated <code>msg.value</code> is accepted by some contract that does give us credit? We could achieve the impossible and attack WETH to make it depeg!</p><p>The WETH contract allows users to deposit native ETH that users specify through <code>msg.value</code>. It stores this value internally after transferring the appropriate amount of tokens. Normally if you don&#8217;t have enough balance for the transfer, the transaction will be rejected or reverted. However, since we have bypassed the transfer validation by truncating to 0, the contract is willing to add our gigantic credit to our address in its internal balance mappings. Suddenly we have an astronomical balance in the contract and can drain all the deposited native tokens from the wrapped token contract!</p><p>To clarify, it&#8217;s not the WETH token itself on Ethereum that is vulnerable (but the title made you click, didn't it!), but the analogous wrapped native tokens of the polkadot parachains powered by the frontier EVM, such as WASTR in Astar, WGLMR in Moonbeam, and WMOVR in Moonriver, which are implemented using the standard WETH contract but on their respective parachains!</p><p>WETH contracts are not the only vulnerable targets. The Uniswap-like DEX trading pair contract accepts direct swapping from native ETH to ERC20 tokens. It trusts the <code>msg.value</code> too. Compound-like lending protocols usually provide a dedicated native token vault, handling both the deposit and withdrawal of native tokens. DEXes and lending protocols are the fundamental infrastructure of the DeFi world, any insolvency would be contagious. As I mentioned, any critical vulnerability that could depeg WETH is actually the nightmare of the whole ecosystem.</p><p>The <a href="https://pwning.mirror.xyz/okyEG4lahAuR81IMabYL5aUdvAsZ8cRCbYBXh8RHFuE">previous bug</a> had a similar effect, but required a tricky exploit. This bug is trivial but more destructive.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!w3pR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!w3pR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 424w, https://substackcdn.com/image/fetch/$s_!w3pR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 848w, https://substackcdn.com/image/fetch/$s_!w3pR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 1272w, https://substackcdn.com/image/fetch/$s_!w3pR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!w3pR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png" width="902" height="1068" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8642c38-886c-42d5-9d45-a8458946210e_902x1068.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1068,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;the exploit&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="the exploit" title="the exploit" srcset="https://substackcdn.com/image/fetch/$s_!w3pR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 424w, https://substackcdn.com/image/fetch/$s_!w3pR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 848w, https://substackcdn.com/image/fetch/$s_!w3pR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.png 1272w, https://substackcdn.com/image/fetch/$s_!w3pR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8642c38-886c-42d5-9d45-a8458946210e_902x1068.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>The impact of the bug is complex. The direct exploit could drain all the wrapped token contracts. In addition to taking over the balance of the wrapped token, you can purchase other tokens from DEX by spending the rubber check from the wrapped token. Worse, a more sophisticated exploit could leverage the lending protocol to borrow all the other valuable tokens against the fake deposit.</p><p>At the time I reported the bug, the major victims were:</p><ul><li><p><em><strong>WMOVR</strong></em> <a href="https://moonriver.moonscan.io/address/0x98878b06940ae243284ca214f92bb71a2b032b8a">https://moonriver.moonscan.io/address/0x98878b06940ae243284ca214f92bb71a2b032b8a</a> 560,369.286709772080185324 MOVR $6,511,491.11 (@ $11.62/MOVR)</p></li><li><p><em><strong>WMOVR</strong></em> <a href="https://moonriver.moonscan.io/address/0xf50225a84382c74cbdea10b0c176f71fc3de0c4d">https://moonriver.moonscan.io/address/0xf50225a84382c74cbdea10b0c176f71fc3de0c4d</a> 39,495.093378689025337841 MOVR $458,932.99 (@ $11.62/MOVR)</p></li><li><p><em><strong>MGLMR</strong></em> <a href="https://moonbeam.moonscan.io/address/0xacc15dc74880c9944775448304b263d191c6077f">https://moonbeam.moonscan.io/address/0xacc15dc74880c9944775448304b263d191c6077f</a> 22,509,169.750566904824477505 GLMR $15,462,674.16 (@ $0.69/GLMR)</p></li><li><p><em><strong>Wrapped Astar</strong></em> <a href="https://blockscout.com/astar/address/0xAeaaf0e2c81Af264101B9129C00F4440cCF0F720">https://blockscout.com/astar/address/0xAeaaf0e2c81Af264101B9129C00F4440cCF0F720</a> 233,903,992.470478147048553875 ASTR ($12,110,613 USD)</p></li><li><p><em><strong>WASTR</strong></em> <a href="https://blockscout.com/astar/address/0x19574c3c8FaFc875051b665Ec131b7E60773d2C9">https://blockscout.com/astar/address/0x19574c3c8FaFc875051b665Ec131b7E60773d2C9</a> 98,294,128.445114886025015582 ASTR ($5,080,234 USD)</p></li><li><p><em><strong>Wrapped Shiden</strong></em> <a href="https://blockscout.com/shiden/address/0x0f933Dc137D21cA519ae4C7E93f87a4C8EF365Ef">https://blockscout.com/shiden/address/0x0f933Dc137D21cA519ae4C7E93f87a4C8EF365Ef</a> 9,348,196.210407926441765242 SDN ($3,310,196)</p></li></ul><p>The direct loss from wrapped token contracts could be more than <strong>$44M</strong>.</p><p>In lending pools the assets under risk is even larger:</p><ul><li><p><em><strong>Moonwell Apollo</strong></em> Total Supply $89,023,722 Total Borrow $41,595,374.52</p></li><li><p><em><strong>Moonwell Artemis</strong></em> Total Supply $179,023,716.01 Total Borrow $94,486,490.85</p></li><li><p><em><strong>Starlay Finance</strong></em> Total Deposited $37,163,238.35 Total Borrowed $18,769,822.51</p></li></ul><p>The remaining borrowable assets would be somewhere around <strong>$150M</strong>.</p><p>The vulnerability disclosure was troublesome as well. This bug affected at least two parachains: Moonbeam network and Astar network. I had to report to them simultaneously otherwise one team with earlier knowledge of the bug could conceivably launch an attack on the other one (I didn&#8217;t know if they were competitors). Furthermore, I noticed Acala network also shipped the same code, but they didn&#8217;t have as rich an EVM-based ecosystem as the other two, and the bug had no explicit impact on their system as a result, so I decided to postpone the bug disclosure to them.</p><p>All the three projects have their bug bounty program listed on Immunefi: <a href="https://web.archive.org/web/20220521163014/https://immunefi.com/bounty/moonbeamnetwork/">Moonbeam network</a>, <a href="https://web.archive.org/web/20220625225821/https://immunefi.com/bounty/astarnetwork/">Astar network</a> and <a href="https://web.archive.org/web/20220625224811/https://immunefi.com/bounty/acala/">Acala</a>. Each project has a maximum bug bounty of <strong>$1M</strong> &#128558;. I was worried that the triage process on Immunefi might be delayed, so I tried to contact the first two teams as soon as I finished my <a href="https://app.ardrive.io/#/drives/b7ecc2e5-bbe6-4ac3-91a2-c4d5a6bb2fff?name=FRONTIER">POC and reports</a>. Thanks to the help from the <a href="https://moonwell.fi/">Moonwell</a> team, they set up a telegram channel between me and Moonbeam, who later invited the Astar and Polkadot guys to the group. All the bugs were quickly <a href="https://github.com/paritytech/frontier/pull/753">patched</a>. A <a href="https://github.com/paritytech/frontier/security/advisories/GHSA-hc8w-mx86-9fcj">security advisory</a> (CVE-2022-31111) was published later. This has been recorded on Moonbeam&#8217;s <a href="https://moonbeam.network/blog/security-patch-for-integer-truncation-bug/">blog</a>.</p><p>Another interesting fact about the bug: a few hours after my report, the Moonbeam team identified a suspicious <a href="https://moonriver.moonscan.io/tx/0xbb8913dfb35b70caa42da03fb874dc42768700c15b858d9fb30a2d672a497262">transaction</a> that triggered the vulnerability. You can see the transfer of 340,282,366 (T) MOVR! I believe the bug is dead now, but the corpse is living on the blockchain permanently.</p><p>The vulnerable substrate <code>frontier</code> is built by <a href="https://www.parity.io/">paritytech</a>, the team behind <a href="https://polkadot.network/">Polkadot</a>. The Moonbeam team maintains its own fork at <a href="https://github.com/PureStake/frontier">https://github.com/PureStake/frontier</a>. The Astar team forks from Moonbeam&#8217;s repo to <a href="https://github.com/AstarNetwork/frontier">https://github.com/AstarNetwork/frontier</a>. All of them agreed to offer a bug bounty, but they decided to split a $1M bounty after months of negotiation&#129315;. To my surprise, Acala offered a huge bounty (compared to their negligible potential loss), which was also counted in the split. The final payout is $1M:</p><ul><li><p><em><strong>Moonbeam</strong></em> $430k</p></li><li><p><em><strong>Astar</strong></em> $250k</p></li><li><p><em><strong>Polkadot</strong></em> $250k, in DOT</p></li><li><p><em><strong>Acala</strong></em> $70k, in DOT</p></li></ul><p>Whether the result is $2M or $1M, since the bounty pays out in tokens living on the Ethereum blockchain, I guess I'm pretty lucky that WETH wasn't vulnerable to this bug after all!</p>]]></content:encoded></item><item><title><![CDATA[The Defrauded Fraud Proof of A Bitcoin Bridge]]></title><description><![CDATA[Hanging out in the Immunefi discord leads me to new wonderlands! Last month I was notified of a new bounty program from Interlay, who claimed the maximal bounty payout could be $1M. Although the mainnet of its BTC bridge was not launched, they promised a minimum reward of]]></description><link>https://blog.offside.io/p/the-defrauded-fraud-proof-of-a-bitcoin-bridge</link><guid isPermaLink="false">https://blog.offside.io/p/the-defrauded-fraud-proof-of-a-bitcoin-bridge</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Sun, 31 Jul 2022 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4de1ddda-c02b-4e38-a535-b667af88aa79_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hanging out in the Immunefi discord leads me to new wonderlands! Last month I was notified of a new bounty program from Interlay, who claimed the maximal bounty payout could be $1M. Although the mainnet of its BTC bridge was not launched, they promised a minimum reward of <a href="https://web.archive.org/web/20220630180653/https://immunefi.com/bounty/interlay/">$100k</a> for critical bug reports.</p><p>This journey took me out of the safety of the moonlight and into the uncertain darkness of collateralization. I dug into new concepts to bring familiarity to unfamiliar code. I quickly found a trivial bug, but I suspected that there was more. After some comprehensive research, I discovered a novel, exciting flaw. Both bugs have been confirmed as critical, leading to the decision to deactivate the vulnerable module.</p><p>To understand the hack, you, like I had to do, will have to start with the basics. So sit back, read on, and let's learn about collateral!</p><h2>the interBTC Bridge and Over-collateralization</h2><blockquote><p>The interBTC runtime allows the creation of interBTC, a fungible token that represents Bitcoin in the Polkadot ecosystem. Each interBTC is backed by Bitcoin 1:1 and allows redeeming of the equivalent amount of Bitcoins by relying on a collateralized third-party.</p></blockquote><p>Over-collateralization is a popular technique in DeFi protocols, enabling the minting of a synthesized asset from another base asset. Most Collateralized Debt Position (CDP) protocols are designed for minting stable coins from valuable but volatile assets. The most successful case of over-collateralization is the <a href="https://makerdao.com/">MakerDAO</a> protocol, which allows users to create debt in DAI by depositing ETH.</p><p>In the interBTC protocol, however, one is allowed to synthesize a mapping of a high value token (BTC) from its native tokens, like INTR and KINT. This feature is more like <a href="https://synthetix.io/">Synthetix</a>, which allows minting any mapped assets by locking its native token SNX. The security of risky collateral usually means higher collateralization rate and lower capital efficiency. For SNX, the <a href="https://docs.synthetix.io/litepaper/">Collateralization Ratio</a> (C-Ratio) is 400%. For interBTC, on their Kintsugi canary network, C-Ratio of KINT is 500%, C-Ratio of KSM (the native token of Kusama) is 150%.</p><p><strong>As pointed out by the interlay team, they use mainly the KSM/DOT assets (the ceiling of INTR/KINT is very low due to missing liquidity). They primarily target exogenously priced collateral assets rather than endogenous ones - more like Maker, but they allow a small portion of our native asset.</strong></p><p>The security properties are usually maintained by price oracles and arbitrageurs, but this may not work during market crashes. Luckily, the over-collateralization of interBTC is just the &#8203;&#8203;last line of defenses, the system has guaranteed Bitcoin reserves as long as all the vaults are honest.</p><p>But how can we trust decentralized vaults that are controlled by anonymous entities? Now I will try to explain the innovation of interBTC&#8217;s fraud proof and slashing mechanisms.</p><h2>Onchain SPV and Fraud Proof</h2><p>InterBTC is designed specifically for BTC, so it has to deal with the complexity of bitcoin transactions. It is clearly impossible to maintain all the transactions on chain, so the protocol works like a light wallet. Accordingly, the <a href="https://spec.interlay.io/security_performance/btcrelay-security.html">BTC-relay</a> module of the protocol implements the <a href="https://en.bitcoinwiki.org/wiki/Simplified_Payment_Verification">Simplified Payment Verification</a> (SPV). Instead of tracking all the unspent notes (utxo), only the minimal information of every bitcoin block header is stored on the chain. The relayers are in charge of the synchronization of block headers, providing the root of trust. The validation algorithm only needs to verify a given transaction</p><ol><li><p>has a valid merkle proof for its txid</p></li><li><p>the merkle root is found in the stored block headers</p></li><li><p>the corresponding block is mature enough</p></li></ol><p>Thus the system is able to check the validity of any interactions between users and vaults (specifically, transfers of a specific amount of BTC). Where would the users deposit to? To addresses prepared by the vaults in the <a href="https://spec.interlay.io/spec/vault-registry.html">registry</a> module. The vaults have to respond to reasonable requests from the user, and if no valid proof is supplied in a limited time, the locked collateral for that request will be slashed. All the required information is provided to the system, so it can confirm the honest behaviors with confidence.</p><p>What about malicious behaviors without corresponding user requests? The off-chain relayers monitor and check that vaults do not move BTC, unless expressly requested during <code>Redeem</code>, <code>Replace</code> or <code>Refund</code>. If a malicious vault moves BTC without authorization by the bridge, or reuses the authorization by committing the same <code>OP_RETURN</code> transaction, all of its collateral will be slashed. These two behaviors are reported by <code>report_vault_theft</code> and <code>report_vault_double_payment</code> extrinsics respectively.</p><p>Therein lie the bugs...</p><h2>Bug 1: Double Payment Force Liquidation</h2><p><code>report_vault_double_payment</code> is exposed as an extrinsic call method. It takes two raw txs and verifies that they share the same input and reference the same user requests.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!u_XB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!u_XB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 424w, https://substackcdn.com/image/fetch/$s_!u_XB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 848w, https://substackcdn.com/image/fetch/$s_!u_XB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 1272w, https://substackcdn.com/image/fetch/$s_!u_XB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!u_XB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png" width="902" height="764" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:764,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;report_vault_double_payment&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="report_vault_double_payment" title="report_vault_double_payment" srcset="https://substackcdn.com/image/fetch/$s_!u_XB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 424w, https://substackcdn.com/image/fetch/$s_!u_XB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 848w, https://substackcdn.com/image/fetch/$s_!u_XB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.png 1272w, https://substackcdn.com/image/fetch/$s_!u_XB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe82d91e5-dc99-4ea7-bea7-d4fc212a19a7_902x764.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>The two txs are compared to ensure they are different. However, the check of <code>Vec&lt;u8&gt;</code> is incomplete.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i199!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i199!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 424w, https://substackcdn.com/image/fetch/$s_!i199!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 848w, https://substackcdn.com/image/fetch/$s_!i199!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 1272w, https://substackcdn.com/image/fetch/$s_!i199!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i199!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png" width="902" height="262" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:262,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;parse_transaction&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="parse_transaction" title="parse_transaction" srcset="https://substackcdn.com/image/fetch/$s_!i199!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 424w, https://substackcdn.com/image/fetch/$s_!i199!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 848w, https://substackcdn.com/image/fetch/$s_!i199!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.png 1272w, https://substackcdn.com/image/fetch/$s_!i199!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92a8035d-faa7-4ff2-b268-c0fbf5e1be35_902x262.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><code>BytesParser</code> ignores trailing bytes of the raw transaction, so different <code>raw_txs.0</code> and <code>raw_txs.1</code> can be parsed into same <code>Transaction</code>, bypassing all the following checks in <code>report_vault_double_payment</code>.</p><p>All the vaults with at least one processed user request (Redeem, Replace or Refund), are vulnerable to this force liquidation. The attacker would steal 5% of the vault's collateral, leaving the whole system broken: all the collateral would be transferred to the liquidation account and all vaults would be banned.</p><p>The bug is pretty simple. In the <a href="https://app.ardrive.io/#/file/5796e38f-2482-4471-8890-91b18401f96d/view">POC</a>, a fake tx is crafted by simply appending an extra byte to the original tx. My patch and testcase were later adopted in their <a href="https://github.com/interlay/interbtc/commit/3ef1476649697d6f7bbf785e39882ad965bd2ba8">commit</a>. <a href="https://app.ardrive.io/#/file/45c245c8-8b31-4052-9572-f072a54e2c5d/view">Full Report</a></p><h2>Bug 2: P2SH Address Forgery</h2><p>The bitcoin address itself is a pretty interesting topic. There are many variants of <a href="https://learnmeabitcoin.com/technical/address">address</a>: P2PK, P2PKH, P2MS, P2SH, P2WSH, P2WPKH&#8230; It&#8217;s super confusing! Why?</p><p>As you may (should!) already know, there is no such concept as an <em>account</em> in Bitcoin: all the balances are maintained by <a href="https://learnmeabitcoin.com/technical/utxo">utxos</a>. Every utxo has a <a href="https://learnmeabitcoin.com/technical/scriptPubKey">ScriptPubkey</a>, which can only be unlocked by the corresponding ScriptSig. The different types of <a href="https://learnmeabitcoin.com/technical/script">common ScriptPubkey</a> are encoded in addresses of various forms. Notice that they are actually tiny scripts that support limited operations in the special stack-based virtual machine inside Bitcoin.</p><p>The interBTC system currently supports 4 types of addresses: P2PKH, P2SH, P2WPKHv0 and P2WSHv0. The vaults can freely register any type of address. One of these types is particularly interesting, P2SH &#8211; <a href="https://learnmeabitcoin.com/technical/p2sh">Pay To Script Hash</a>. This feature has a subtle quirk: any ScriptPubkey can be encoded in a vault address with just its hash, and the actual ScriptPubKey will only be provided by the corresponding ScriptSig (and verified against the stored hash). Subsequently, the rest of the ScriptSig (which is not checked against any hashes), just like the key to a lock, can be forged arbitrarily to match the mutable ScriptPubkey!</p><p>The malleability of ScriptSig is not a nightmare until it is used in a SPV system. Due to the reduced amount of information stored in SPV, there is no way to lookup the matching ScriptPubkey of a ScriptSig (unlike a full node, which can look it up in the chain). So the system has to extract the ScriptPubkey/address from the ScriptSig. The extraction of the address must be accurate, otherwise</p><ul><li><p>Attack 1: If the correct address is not recovered from the ScriptSig, the use of the uxto will not be considered as the action of the vault, thus the misbehavior will never be confirmed by <code>report_vault_theft</code>.</p></li><li><p>Attack 2: If the extracted address is misinterpreted as an address of another vault, the benign vault will be slashed by <code>report_vault_theft</code>.</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_!aK0v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aK0v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 424w, https://substackcdn.com/image/fetch/$s_!aK0v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 848w, https://substackcdn.com/image/fetch/$s_!aK0v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 1272w, https://substackcdn.com/image/fetch/$s_!aK0v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aK0v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png" width="902" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;extract_address_hash_scriptsig&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="extract_address_hash_scriptsig" title="extract_address_hash_scriptsig" srcset="https://substackcdn.com/image/fetch/$s_!aK0v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 424w, https://substackcdn.com/image/fetch/$s_!aK0v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 848w, https://substackcdn.com/image/fetch/$s_!aK0v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.png 1272w, https://substackcdn.com/image/fetch/$s_!aK0v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8e361d0-d103-4c90-b1ec-dc50d2fd805a_902x808.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>Unfortunately, the address extraction algorithm is neither sound nor complete. For example, it only accepts a subset of valid addresses and detects the P2SH address by checking if the first opcode is <code>OP_0</code>. If the ScriptSig violates the hardcoded templates of P2SH and P2PKH, the correct address will not be recognized, leading to Attack 1. If the ScriptSig is carefully crafted by the attacker, any P2PKH or P2SH addresses can be counterfeited. That is Attack 2. It's worth noting that Attack 1 can be a side-effect of Attack 2.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RuPE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RuPE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 424w, https://substackcdn.com/image/fetch/$s_!RuPE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 848w, https://substackcdn.com/image/fetch/$s_!RuPE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 1272w, https://substackcdn.com/image/fetch/$s_!RuPE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RuPE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png" width="902" height="474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f1a19036-746c-4512-847f-afdb41909556_902x474.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:474,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;poc-2.py&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="poc-2.py" title="poc-2.py" srcset="https://substackcdn.com/image/fetch/$s_!RuPE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 424w, https://substackcdn.com/image/fetch/$s_!RuPE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 848w, https://substackcdn.com/image/fetch/$s_!RuPE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.png 1272w, https://substackcdn.com/image/fetch/$s_!RuPE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1a19036-746c-4512-847f-afdb41909556_902x474.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>In the <a href="https://app.ardrive.io/#/file/9cd69395-ad2f-48d6-89a5-66e97e94de4d/view">POC</a>, I use a P2SH address corresponding to a special redeem script and construct a transaction by spending from that P2SH address. The redeem script consumes 3 elements from stack: [fake sig, fake pubkey, real sig]. It has two <code>OP_NIP</code> opcodes that drop the first two elements of the input stack. The remaining <code>real sig</code> is verified with the hardcoded real pubkey. Because the first two elements, sig and pubkey, are pushed into stack just like other common P2PKH scriptsig, the extracted address from this scriptsig will be just like a normal P2PKH address from the fake pubkey (the fake sig is unused), thus leading to Attack 2. The <a href="https://blockstream.info/testnet/tx/e0d2457036493db0787636a926b543f96dbfca157a6ca81d5fb97f2cc70e1e5b?expand">transaction</a> has been confirmed in the testnet. <a href="https://app.ardrive.io/#/file/14e8a1a0-1dcf-4921-88a4-041d8f4959d5/view">Full Report</a>.</p><p>Patching the design failure is tricky: introducing stricter validations means more chances of missing actual thefts. The interlay team handled the issue quickly and decided to deactivate the vulnerable theft reporting functions. However, my exploration didn&#8217;t stop here.</p><h2>Bonus: Segwit Address Confusion</h2><p>The P2SH address is not the only type of address with a customized script. P2WSH, the <a href="https://en.bitcoin.it/wiki/Segwit">segwit</a> version of P2SH, works in a similar fashion, but the script is revealed inside of the witnesses instead of the ScriptSig. P2WPKH is another specially handled address type, validating the user public key embedded in witnesses. For both cases, there is a deterministic algorithm to infer the correct address from the witnesses. I failed to break the segwit style addresses at first, but eventually I found a weakness!</p><p>The extraction algorithm only cares about the last element of the witnesses, because it is either the public key for P2WPKH, or the ScriptPubkey for P2WSH.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Kdjy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Kdjy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 424w, https://substackcdn.com/image/fetch/$s_!Kdjy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 848w, https://substackcdn.com/image/fetch/$s_!Kdjy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 1272w, https://substackcdn.com/image/fetch/$s_!Kdjy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Kdjy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png" width="902" height="512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44633291-7dd8-439d-8baa-b16839d2057e_902x512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:512,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;extract_address_hash_witness&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="extract_address_hash_witness" title="extract_address_hash_witness" srcset="https://substackcdn.com/image/fetch/$s_!Kdjy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 424w, https://substackcdn.com/image/fetch/$s_!Kdjy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 848w, https://substackcdn.com/image/fetch/$s_!Kdjy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.png 1272w, https://substackcdn.com/image/fetch/$s_!Kdjy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44633291-7dd8-439d-8baa-b16839d2057e_902x512.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>So, how can an SPV system determine the exact type of the original address in the unified algorithm? Heuristics again! If the witness of P2WSH address looks like a valid public key:</p><ol><li><p>length in 33 bytes</p></li><li><p>first byte is &#8216;\x03&#8217; or &#8216;\x04&#8217;</p></li></ol><p>then it is considered a valid P2WPKH address.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hk6Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hk6Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 424w, https://substackcdn.com/image/fetch/$s_!hk6Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 848w, https://substackcdn.com/image/fetch/$s_!hk6Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 1272w, https://substackcdn.com/image/fetch/$s_!hk6Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hk6Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png" width="902" height="458" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:458,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;bonus.py&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="bonus.py" title="bonus.py" srcset="https://substackcdn.com/image/fetch/$s_!hk6Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 424w, https://substackcdn.com/image/fetch/$s_!hk6Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 848w, https://substackcdn.com/image/fetch/$s_!hk6Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.png 1272w, https://substackcdn.com/image/fetch/$s_!hk6Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1edaee97-5d8a-4969-9dc1-4db7caa22274_902x458.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>Some knowledge of the opcodes is required for building this <a href="https://app.ardrive.io/#/file/ed8af0ee-1513-4c02-9266-1a41c72bf57a/view">tricky script</a>. The confirmed <a href="https://blockstream.info/testnet/tx/478830a64f4bb962d151c7248d03b1e76e8e99224b475f8dd3550c96f8cea09a?expand">transaction</a> is on the testnet.</p><h2>Downgraded Security?</h2><p>In the <a href="https://medium.com/interlay/kintsugi-released-urgent-security-patches-aebf969ee087">postmortem</a> of the interlay team, they have decided to remove the theft reporting functions. As we have discussed in the first section, the removal of fraud proof downgrades the security: it degenerates interBTC into a basic over-collateralization system, just like Synthetix. Will it be a problem? In theory, its economic security is <strong>unaffected</strong>.</p><p><strong>There is no guarantee that a vault still holds BTC, but the value at risk for the vault is still the same. So if a vault does not send BTC at the time of redemption it is still the same decision process: keep BTC or lose collateral at the time when the user redeems.</strong></p><p>However, the security achieved through sophisticated economic designs does not always work. While searching for more instances of failed fraud proof, I came across an unexpected protocol, <a href="https://github.com/harmony-one/onebtc">ONEBTC</a>, the &#8220;Trustless Bitcoin on Harmony&#8221;. They listed <code>interlay/BTC-Bridge</code> and <code>interlay/BTC-Bridge-Spec</code> in their references! Their code looks like an old version of interlay BTC bridge, with some random customizations (comment out some functions deliberately).</p><p>In <a href="https://github.com/harmony-one/onebtc/blob/main/contract/bridge/contracts/OneBtc.sol">OneBTC.sol</a>, they have implemented <code>reportVaultTheft</code> and <code>reportVaultDoublePayment</code>! But these functions are restricted by requiring <code>relay.isApprovedStakedRelayer(msg.sender)</code>, and they don&#8217;t really parse the transactions &#8211; they just slash anybody unconditionally!</p><p>I have not verified if they had ever used the fraud proof functions, but even if that happened, it would not be in a <code>trustless</code> style as they claimed (and users expected). It turned out that the &#8220;optimistic&#8221; and semi-trustless bridge worked pretty well, the decentralized nature of vaults were immune to the compromised private key! The ONEBTC bridge was the only survivor of <a href="https://medium.com/harmony-one/harmonys-horizon-bridge-hack-1e8d283b6d66">the epic nine figure hack</a>.&#128531;</p><p>Funds SAFU? Maybe not... The fluctuation of its collateral, Harmony (ONE), caused a huge risk of under-collateration. The emergency (still ongoing!) freeze of the bridge reinforced the crisis. The users might not be able to cash out, but the vault operators can leave this dangerous game freely, because the raw Bitcoin is unstoppable!</p><h2>Closing Thoughts</h2><p>Given the potential for deceit that we find again and again in not just crypto, but almost every inter-human transaction, did we truly expect it to hold secure? Humans have been forging coins, cash, and checks for centuries. Is it really unexpected that, given the chance, we would forge <em>scripts</em>?</p><p>What keeps the darkness at bay? I hope that, in a small part, I've helped keep it at bay with this report. Perhaps there was a potential future with a headline of an interBTC hack that now won't happen. Perhaps not. But what there is, is you. I am but one hacker, just months into my crypto journey. You can come walk it with me: what took me months can take you weeks, and you, too, can keep crypto safe.</p>]]></content:encoded></item><item><title><![CDATA[How to Steal $100M from Flawless Smart Contracts]]></title><description><![CDATA[Embark on an exciting journey as I expose a critical design flaw in Moonbeam's network, safeguarding over $100M and earning a $1M bug bounty reward.]]></description><link>https://blog.offside.io/p/how-to-steal-100m-from-flawless-smart-contracts</link><guid isPermaLink="false">https://blog.offside.io/p/how-to-steal-100m-from-flawless-smart-contracts</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Tue, 28 Jun 2022 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/3f28804b-dec8-4cf6-b501-200afc8312f0_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote><p>&#128161; Read the original post here: https://pwning.mirror.xyz/okyEG4lahAuR81IMabYL5aUdvAsZ8cRCbYBXh8RHFuE</p></blockquote><p>My blockchains adventure continues! This time I protected Moonbeam network by disclosing a critical design flaw, safeguarding more than $100M assets at risk in various DeFi projects. I was awarded the maximum reward amount of their bug bounty program on <a href="https://immunefi.com/bounty/moonbeamnetwork/">Immunefi</a>, $1M, and $50k bonus from <a href="https://immunefi.com/bounty/moonwell/">Moonwell</a> (I guess that&#8217;s also one of the top 10 highest bug bounties?)</p><p>After reporting <a href="https://mirror.xyz/pwning.eth/CB4XUkbJVwPo7CaRwRmCApaP2DMjPQccW-NOcCwQlAs">the bug in Aurora engine</a>, I started to think about the other potential misuses of delegate calls of native contracts. The original purpose of the <code>delegatecall</code> was to provide a mechanism through which one smart contract could share and reuse the code of another one&#8217;s to avoid the overhead of duplicated code storage. Native contracts are usually prebuilt contracts that implement special functions as extensions of the original EVM.</p><p>Now, the tricky part: if you <code>delegatecall</code> to a native contract, you may be able to execute some unexpected functions, even privileged ones! However, the developers of those native contracts might not realize that the actual user of the functions could be someone else. In the Aurora bug's case, the native contract just assumes the caller will always be a magical address, so the hardcoded log emitter leads to the malicious withdrawal vulnerability.</p><p>What other assumptions could be wrong? When you do a <code>delegatecall</code>, the calling context is inherited from the previous one, including the <code>msg.sender</code> and <code>msg.value</code>. From the view of a native contract, the contract that invokes <code>delegatecall</code> is transparent: its caller will be considered the real user instead. So if a malicious contract is invoked, it can impersonate its caller to operate on the native contracts!</p><h1>Shadow in the Moonbeam</h1><p>Moonbeam and Moonriver are both EVM-compatible platforms. There are some precompiled contracts in moonbeam runtime which are shared between Moonbeam and Moonriver.</p><p>The Balance ERC-20 precompile provides an ERC-20 interface for handling the native tokens (<code>MOVR</code> &amp; <code>GLMR</code>) of balance. The implementation <code>Erc20BalancesPrecompile</code> is in <code>moonbeam/precompiles/balances-erc20/src/lib.rs</code>.</p><p>The designer did not take the usage of <code>delegatecall</code> in EVM into consideration. A malicious contract can pass its <code>msg.sender</code> to the precompile contract to impersonate its caller. In this scenario, there is no way for the precompile contract to figure out the actual caller. The attacker can either increase the allowance from the victim or transfer the available balance immediately.</p><p>There are similar issues in the Asset ERC-20 precompile, which provides an ERC-20 native implementation of interoperable tokens (<code>xcKSM</code>, <code>xcDOT</code>, ...). The implementation <code>Erc20AssetsPrecompileSet</code> is in <code>moonbeam/precompiles/assets-erc20/src/lib.rs</code>.</p><p>However, the designer <em>did</em> consider the usage of <code>delegatecall</code> in EVM for this case. The <code>ERC20Instance</code> contract in the tests has implemented <code>approve_delegate()</code>, <code>transfer_delegate()</code> and <code>transferFrom_delegate()</code>, with test cases ensuring their validity. Unfortunately (or, for us, fortunately!), it turns out that the design logic can not work properly, so they have removed the relevant code in their <a href="https://github.com/PureStake/moonbeam/pull/1551/files#diff-1404c7c10c00572e96e647084d96576f592a2c18e70f53cdcfec2daa98adb60cR119">patch</a>.</p><p>Here is a simple exploit that can be reused in both cases: the `asset` address of native token is <code>0x0000000000000000000000000000000000000802</code> and the <code>asset</code> address of a local token could be <code>0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bU2N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bU2N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 424w, https://substackcdn.com/image/fetch/$s_!bU2N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 848w, https://substackcdn.com/image/fetch/$s_!bU2N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 1272w, https://substackcdn.com/image/fetch/$s_!bU2N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bU2N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp" width="1456" height="1609" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1609,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:281148,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bU2N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 424w, https://substackcdn.com/image/fetch/$s_!bU2N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 848w, https://substackcdn.com/image/fetch/$s_!bU2N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 1272w, https://substackcdn.com/image/fetch/$s_!bU2N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F53c816bd-fc0c-4ab2-8170-123b2dbb89e2_2298x2540.webp 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><h1>Perfect Contracts, or Perfect Victims?</h1><p>What can we do with the design flaw? The basic idea is to ask someone to trigger your malicious contract, e.g., calling the `trap()` in the POC contract.</p><p>How can we persuade users to invoke some mysterious contracts? By Airdrop! The hackers behind the <code>UNIH</code> token have demonstrated the crypto-native solution of <a href="https://www.runebase.org/news/beware-of-unih-airdrop/">phishing</a>! Any user who wants to sell an airdropped token in uniswap has to call the malicious token contract to approve the DEX to spend their balance. Due to the vulnerable design of RUNE tokens, where only the <code>tx.origin</code> instead of <code>msg.sender</code> is checked for approval, all the RUNE tokens could be stolen by a trojan contract.</p><p>The phishing idea is creative, but it strongly limits the potential damage of the vulnerability. We want to find a better victim that is</p><ol><li><p>willing to call your contract</p></li><li><p>not as smart as users</p></li><li><p>rich!</p></li></ol><p>Who are the best friends of poor hackers? The flash loan providers! They hold a lot of money and call your contract callbacks as you wish! In the flash loan callback, they are forced to approve your future transfer of their asset tokens, even if they are flawless contracts!</p><p>Some DEX pairs support callbacks to arbitrary contracts, such as SolarBeam on MoonRiver and StellaSwap on Moonbeam. The stable swap pair between <code>xcKSM</code> and <code>stKSM</code> is also vulnerable due to the support of flash loans. If one token can be drained from the trading pair, then the other token can be moved out in one single swap, all the liquidity will be cleared.</p><p>Now the perfect written contracts become perfect victims. By the time I reported, the richest vulnerable contracts were:</p><ul><li><p><a href="https://moonriver.moonscan.io/address/0xea3d1e9e69addfa1ee5bbb89778decd862f1f7c5">0xea3d1e9e69addfa1ee5bbb89778decd862f1f7c5</a> on Moonriver, SolarBeam LP Token, $7.5M</p></li><li><p><a href="https://moonbeam.moonscan.io/address/0xa927e1e1e044ca1d9fe1854585003477331fe2af">0xa927e1e1e044ca1d9fe1854585003477331fe2af</a> on Moonbeam, Stella LP Token, $2.7M    </p></li><li><p><a href="https://moonriver.moonscan.io/address/0x77d4b212770a7ca26ee70b1e0f27fc36da191c53">0x77d4b212770a7ca26ee70b1e0f27fc36da191c53</a> on Moonriver, xcKSM &amp; stKSM pair, $2.4M</p></li></ul><p>These tokens are worth about $12.6M, even a 10% potential loss is already more than $1M, the maximal bounty prize that Moonbeam offers. But real hackers won&#8217;t be stopped by trivial achievements, will there be any crazier victims?</p><h1>the Glimmer</h1><p>The native tokens <code>MOVR</code> (on Moonriver) and <code>GLMR</code> (on Moonbeam) are equivalent to <code>ETH</code> on Ethereum. To be used in DeFi protocols, they have to be wrapped in ERC-20 compatible token contracts, just like <code>WETH</code>.</p><p>The Balance ERC-20 precompile provides the native wrapper of the native tokens. None of any deployed protocols ever use it because the official wrapped tokens <code>WMOVR</code> and <code>WGLMR</code> are more widely adopted. By leveraging the vulnerability of the Balance ERC-20 precompile, we are able to steal the native token balance from any userif it invokes the malicious contract. Unlike the Asset ERC-20 precompile tokens, e.g., <code>xcKSM</code> and <code>xcDOT</code>, which are directly used by DEXes, <code>MOVR</code> and <code>GLMR</code> balances are rarely used by smart contracts.</p><p>Most contracts with non-zero balances are multisig wallets, which are not so different from the externally owned accounts. The only exception, our glimmer of hope, is the <code>MGlimmer</code> contract of the Moonwell project.</p><p>The Moonwell project is the dominant DeFi protocol on Moonriver. It has nearly $200M in supply and $100M available for borrowing (at the time I reported). <code>MGlimmer</code>, or <code>Moonwell: mMOVR Token</code> is the specific contract that handles the lending and borrowing against <code>MOVR</code>, and it has the native <code>MOVR</code> in its balance.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IGhD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IGhD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 424w, https://substackcdn.com/image/fetch/$s_!IGhD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 848w, https://substackcdn.com/image/fetch/$s_!IGhD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 1272w, https://substackcdn.com/image/fetch/$s_!IGhD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IGhD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp" width="876" height="126" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:126,&quot;width&quot;:876,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16816,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IGhD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 424w, https://substackcdn.com/image/fetch/$s_!IGhD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 848w, https://substackcdn.com/image/fetch/$s_!IGhD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 1272w, https://substackcdn.com/image/fetch/$s_!IGhD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e1d81eb-ae82-4483-ab01-4df0beae32dd_876x126.webp 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The cool thing is that when it transfers the balance to the user, it will call the destination as a contract! Here is a simple exploit that gains the approval of spending all the balance of <code>MGlimmer</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YVaV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YVaV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 424w, https://substackcdn.com/image/fetch/$s_!YVaV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 848w, https://substackcdn.com/image/fetch/$s_!YVaV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 1272w, https://substackcdn.com/image/fetch/$s_!YVaV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YVaV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp" width="1456" height="838" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:838,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87235,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YVaV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 424w, https://substackcdn.com/image/fetch/$s_!YVaV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 848w, https://substackcdn.com/image/fetch/$s_!YVaV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 1272w, https://substackcdn.com/image/fetch/$s_!YVaV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60649c7b-7509-481d-bda8-e3dddd79e476_1808x1040.webp 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>The balance stored in the vulnerable contract is not too much (a few thousand of <code>MOVR</code> now). Still, any amount you deposit into that contract will be considered your collateral in this lending protocol. The exploit can be further weaponized by repeating the deposit &#8594; borrow &#8594; transfer all back &#8594; leave bad debt procedure. All borrowable assets can be drained!</p><p>It could absolutely be in the top 10 heists of DeFi history if any hacker took all the $100M borrowable assets plus $12M vulnerable tokens in DEX pairs! Another amazing fact about these vulnerabilities is that actual attacks could be super stealthy by only keeping the unauthorized privilege instead of stealing immediately. Since the contracts themselves are flawless, it&#8217;s almost impossible for the developers of those DeFi projects to figure out what is going wrong!</p><h1>Responsible Disclosure</h1><p>Everybody is struggling in the bear market. I don&#8217;t want to hurt anyone, I want to help, especially when they are such hard working teams. So I tried my best to help the project teams understand the root causes and speed up the patching process.</p><p>The situation here is extremely complex at first. The flaw is in the deep core of the blockchain system, but the victims are the DeFi protocols built on top of it. Some protocols may have emergency exits to pause and upgrade their contracts, while others are just immutable.</p><p>The ultimate patch has to be made by the Moonbeam team, but the biggest victim, Moonwell, could have mitigations for this vulnerability before the actions of the Moonbeam. I noticed that both Moonbeam and Moonwell had launched their bounty program on Immunefi, so I discussed with the Immunefi team the potential special case (without disclosing the specific name of the projects). After realizing that other projects, like the uniswap style DEXes, can not really do anything useful, I decided not to report to them to minimize the risk of leaking the critical information. Since only the Asset ERC-20 issue might be a problem for the Moonwell team, I have to split the report for Moonbeam into two parts, only the necessary information and the exclusive GlimmerExploit POC are submitted to them.</p><p>I took special care of the Moonbeam team, even if they might not be aware of that. I spent extra hours learning their code base and writing two <a href="https://app.ardrive.io/#/drives/fd36175d-fd51-4a02-8c09-b012dd2f044c?name=MOONBEAM">complete test cases</a> (600+LOC) just in case they needed more explanation of the root cause. I asked the common timezone of the PureStake team in their discord to make sure I submit the report once the first engineer comes to work. Luckily, it worked out: they started handling this issue on Friday and finished the patch before the weekend without any inquiries!</p><p>Is this the last unexpected flaw hiding near the core design of blockchain-based smart contracts? Certainly not! For every <code>delegatecall</code>, there's another, even wilder issue hiding in the darkness. There are always other, more exotic issues waiting for me!. Stay with me on my journey as I find these bugs, push them into the light, and make the blockchain safer for everyone!</p>]]></content:encoded></item><item><title><![CDATA[How did I Save 70000 ETH and Win 6 Million Bug Bounty]]></title><description><![CDATA[Discover how I, pwning.eth, saved 70,000 ETH and won a $6M bug bounty by spotting a crucial flaw in Aurora Engine.]]></description><link>https://blog.offside.io/p/how-did-i-save-70000-eth-and-win-6-million-bug-b</link><guid isPermaLink="false">https://blog.offside.io/p/how-did-i-save-70000-eth-and-win-6-million-bug-b</guid><dc:creator><![CDATA[Offside Labs]]></dc:creator><pubDate>Tue, 14 Jun 2022 16:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/74399b7d-e3a0-4fe3-8012-49435c514413_1024x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nk8a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nk8a!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!nk8a!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!nk8a!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!nk8a!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nk8a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png" width="1200" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1151113,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nk8a!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!nk8a!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!nk8a!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!nk8a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8e84b1d-6fca-46c1-be0f-ebc91c6a8b4e_1200x600.png 1456w" sizes="100vw" fetchpriority="high"></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><blockquote><p>&#128161; Read the original post here: https://pwning.mirror.xyz/CB4XUkbJVwPo7CaRwRmCApaP2DMjPQccW-NOcCwQlAs.</p></blockquote><p>Hi! I am <a href="https://twitter.com/PwningEth">pwning.eth</a>, a wanderer in the hacking space who has recently jumped into the wonderland of crypto. A few months ago, I reported a critical bug in the Aurora Engine, a layer 2 EVM solution built on the NEAR protocol. At least 70000 ETH were at risk of being stolen, until I found the tricky vulnerability and helped the Aurora team fix it. It would be in the <a href="https://rekt.news/leaderboard/">top 5</a> heists in the defi history, if the 200 million tokens were taken over by a blackhat hacker. In the end, I won a bug bounty of 6 million, which was the second highest bounty in history.</p><p>I am an experienced whitehat hacker from the web2 world. I have been watching the hacking drama in the crypto world for a while, and there is so much randomness! I am not too surprised at the astronomical profits of defi hackers, because the criminals in the real world also make an insane amount of money. However, I was really shocked by the <a href="https://www.saurik.com/optimism.html">story</a> of saurik, a famous hacker in the jailbreak community. The size of his bug bounty is unheard of in the traditional security world, and so I can&#8217;t wait to start my own treasure hunt in web3.</p><p>I started by checking the bounty list on Immunefi. The <a href="https://immunefi.com/bounty/aurora/">Aurora bounty program</a>, listed on the very top of the website due to its huge bounty offer, caught my eye. It was a novel project built by a group of talented engineers, which suggested that it might be complex enough to be immune to common defi hackers and mysterious enough for me to learn something magical. Thanks to my experiences in hacking modern complex systems, I was able to start my research on the new blockchains quickly. I had reviewed the Aurora bridge, which was a solid project. Then I moved on to the Aurora engine and discovered the unicorn bug in a few hours. Unlike ordinary defi vulnerabilities, I didn't think this bug could be identified by random people as fast or lucky as me, so I took my time verifying and reproducing the bug in case it was a false alarm. It took me a few days to learn, build, learn, test and finally finish the report.</p><p>I tried pinging the Aurora team in discord, sending messages to the official bounty email and submitting the issue through Immunefi. They confirmed and patched the vulnerability quickly, and have since recounted the general <a href="https://aurora.dev/blog/aurora-mitigates-its-inflation-vulnerability">story</a>. Their rewards for smart contract critical vulnerabilities are calculated as 10% of potential economic damage of their exploitation, up to a value of $6,000,000 USD. In this case, the potential damage could have been higher than ten times this maximum reward. Therefore I was eligible to receive the maximum possible amount, the total value of $6,000,000 USD, in the form of locked AURORA tokens. It&#8217;s a pretty smart and lucky move to be listed on Immunefi :)</p><p>The <a href="https://medium.com/immunefi/aurora-infinite-spend-bugfix-review-6m-payout-e635d24273d">technical details</a> have been explained by Immunefi. Here is my short summary:</p><p>1.  The Aurora engine implements token bridging in prebuilt contracts at hardcoded addresses. They are the magical bridges connecting Ethereum, NEAR and Aurora.</p><p>2.  The vulnerable contract always emits a fixed address in bridging events, assuming the <code>msg.value</code> will be collected by itself. However, if the contract is invoked by <code>delegatecall()</code>, the <code>msg.value</code> will never be sent to the contract but the log will be emitted as usual.</p><p>3.  By repeating the malicious withdrawal then redeposit process, the attacker can double their balance exponentially. The infinity inflation of ETH could have destroyed the whole ecosystem of Aurora: all 71k ETH in the <code>aurora</code> account could have been drained, and other valuable tokens could have been purchased by free ETH. (There were billions of TVL in the Aurora bridge.)</p><p>If you are hardcore enough, you may find the <a href="https://app.ardrive.io/#/drives/7ba902d8-d26a-4dad-99b8-807eaaf8d925?name=AURORA">original report and scripts</a> interesting, enjoy!</p><h2></h2>]]></content:encoded></item></channel></rss>