<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Nekogawa</title>
        <link>https://paragraph.com/@catball</link>
        <description>undefined</description>
        <lastBuildDate>Mon, 20 Jul 2026 11:52:10 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Nekogawa</title>
            <url>https://storage.googleapis.com/papyrus_images/c98c25257781c7e55c0a8b80f0ebf27306b5f4368a272c9f32760cace6caf66c.jpg</url>
            <link>https://paragraph.com/@catball</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[输的吃土 - 盲盒的不正确开盒方式]]></title>
            <link>https://paragraph.com/@catball/QrOHbgTkkkNqVsmsWSGZ</link>
            <guid>QrOHbgTkkkNqVsmsWSGZ</guid>
            <pubDate>Mon, 13 Dec 2021 10:01:22 GMT</pubDate>
            <description><![CDATA[有些人总喜欢玩触发时生成随机数的玩法，那就别怪别人玩输的吃土了。本文是 RACA 盲盒被人用智能合约输的吃土玩成明盒的事故复盘。事故现场BSCScan发生了啥由于 RACA 的智能合约在开盲盒的时候才决定盲盒内容(自己用 Panoramix 看)， 因此我们的攻击者搞了个非常简单的办法弄死了这个盲盒：只要不断的开盒，大奖就会在眼前延伸，不要停下来啊！具体代码def unknown3829d282(uint256 _param1): # not payable require calldata.size - >=′ 32 if not stor1[caller]: revert with 0, 'white only' # 限制只有白名单里的人能用这合约 require ext_code.size(0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e) call 0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e.open(uint256 param1) with: # 开盒合约 gas gas_remaining ...]]></description>
            <content:encoded><![CDATA[<p>有些人总喜欢玩触发时生成随机数的玩法，那就别怪别人玩输的吃土了。本文是 RACA 盲盒被人用智能合约输的吃土玩成明盒的事故复盘。</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">事故现场</h2><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://bscscan.com/address/0xec06e634415ab8d903e1ee6b4f314be99fd56a3b">BSCScan</a></p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">发生了啥</h2><p>由于 RACA 的智能合约在<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://bscscan.com/address/0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e">开盲盒</a>的时候才决定盲盒内容(自己用 Panoramix 看)， 因此我们的攻击者搞了个非常简单的办法弄死了这个盲盒：只要不断的开盒，大奖就会在眼前延伸，不要停下来啊！</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">具体代码</h2><pre data-type="codeBlock" text="def unknown3829d282(uint256 _param1): # not payable
  require calldata.size - &gt;=′ 32
  if not stor1[caller]:
      revert with 0, &apos;white only&apos; # 限制只有白名单里的人能用这合约
  require ext_code.size(0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e)
  call 0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e.open(uint256 param1) with: # 开盒合约
       gas gas_remaining wei
      args _param1
  if not ext_call.success:
      revert with ext_call.return_data[0 len return_data.size]
  require ext_code.size(0x61c6eeca7b14cf4ec1b190dd879008dd7d7e470) 
  static call 0x61c6eeca7b14cf4ec1b190dd879008dd7d7e470.balanceOf(address tokenOwner) with:
          gas gas_remaining wei
         args this.address
  if not ext_call.success:
      revert with ext_call.return_data[0 len return_data.size] # 查询大奖的NFT余额
  require return_data.size &gt;=′ 32
  if ext_call.return_data[0] != 1:
      revert with 0, &apos;no valid&apos;
"><code>def unknown3829d282(<span class="hljs-keyword">uint256</span> _param1): # not <span class="hljs-keyword">payable</span>
  <span class="hljs-built_in">require</span> <span class="hljs-keyword">calldata</span>.size <span class="hljs-operator">-</span> <span class="hljs-operator">></span><span class="hljs-operator">=</span>′ <span class="hljs-number">32</span>
  <span class="hljs-keyword">if</span> not stor1[caller]:
      <span class="hljs-keyword">revert</span> with <span class="hljs-number">0</span>, <span class="hljs-string">'white only'</span> # 限制只有白名单里的人能用这合约
  <span class="hljs-built_in">require</span> ext_code.size(<span class="hljs-number">0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e</span>)
  call <span class="hljs-number">0x4eb7ddd1b0103349fd289c5a4e4b95a0cc68d19e</span>.open(<span class="hljs-keyword">uint256</span> param1) with: # 开盒合约
       gas gas_remaining <span class="hljs-literal">wei</span>
      args _param1
  <span class="hljs-keyword">if</span> not ext_call.success:
      <span class="hljs-keyword">revert</span> with ext_call.return_data[<span class="hljs-number">0</span> len return_data.size]
  <span class="hljs-built_in">require</span> ext_code.size(<span class="hljs-number">0x61c6eeca7b14cf4ec1b190dd879008dd7d7e470</span>) 
  static call <span class="hljs-number">0x61c6eeca7b14cf4ec1b190dd879008dd7d7e470</span>.balanceOf(<span class="hljs-keyword">address</span> tokenOwner) with:
          gas gas_remaining <span class="hljs-literal">wei</span>
         args <span class="hljs-built_in">this</span>.<span class="hljs-built_in">address</span>
  <span class="hljs-keyword">if</span> not ext_call.success:
      <span class="hljs-keyword">revert</span> with ext_call.return_data[<span class="hljs-number">0</span> len return_data.size] # 查询大奖的NFT余额
  <span class="hljs-built_in">require</span> return_data.size <span class="hljs-operator">></span><span class="hljs-operator">=</span>′ <span class="hljs-number">32</span>
  <span class="hljs-keyword">if</span> ext_call.return_data[<span class="hljs-number">0</span>] <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-number">1</span>:
      <span class="hljs-keyword">revert</span> with <span class="hljs-number">0</span>, <span class="hljs-string">'no valid'</span>
</code></pre><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">攻击过程</h2><p>从上面合约代码可以看出，攻击者操作十分简单，不断重复开盒，如果不是大奖则输的吃土，撤销交易。又因为原合约可以重复开盒改变结果，所以盲盒变明盒</p><h2 id="h-" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">结论</h2><p>在区块链这种能撤销交易的环境下，不要在交易的那一刻决定随机数结果，请集中决定盲盒结果（这样反复开盒就成了浪费Gas），或是多少个周期集中派发一次。永远记住，EVM上单个交易是可撤销的。</p>]]></content:encoded>
            <author>catball@newsletter.paragraph.com (Nekogawa)</author>
        </item>
    </channel>
</rss>