<?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>moru</title>
        <link>https://paragraph.com/@moruu</link>
        <description>Blockchain "research" &amp; thoughts, with peace and love.</description>
        <lastBuildDate>Sat, 09 May 2026 20:36:44 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Crypto stealing exploit: a JS entrypoint]]></title>
            <link>https://paragraph.com/@moruu/crypto-stealing-exploit-a-js-entrypoint</link>
            <guid>aHQMaDoFizGt6ixFSL9K</guid>
            <pubDate>Fri, 16 Feb 2024 11:11:18 GMT</pubDate>
            <description><![CDATA[If you are involved in the blockchain or cryptocurrency space, you might own wallets containing valuable assets. It is important to protect your keys with robust security protocols (hardware wallet or air gapped computer). Even if you are careful, you may still fall victim to an attack. Here is a demonstration of how such an exploit works.Step 1: initial contactAfter a conversation on LinkedIn, an individual (the attacker) sent me this message:LinkedIn message, reported. But that was not very...]]></description>
            <content:encoded><![CDATA[<p>If you are involved in the blockchain or cryptocurrency space, you might own wallets containing valuable assets. It is important to protect your keys with robust security protocols (hardware wallet or air gapped computer).</p><p>Even if you are careful, you may still fall victim to an attack. Here is a demonstration of how such an exploit works.</p><h2 id="h-step-1-initial-contact" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 1: initial contact</h2><p>After a conversation on LinkedIn, an individual (the attacker) sent me this message:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/371136b531d52e8f0df086ff34c38cb8750dc91bad9d2e038542aadba348a04a.png" alt="LinkedIn message, reported. But that was not very effective." blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">LinkedIn message, reported. But that was not very effective.</figcaption></figure><p>The assignment looked fishy. I requested more information, but they refused to give any until I completed their task. At this point, I had no interest in working on this task but I knew I was going to find something <em>cool</em> in this repository.</p><h2 id="h-step-2-investigation" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 2: investigation</h2><p>After cloning the repository in a virtual machine, I started looking at every single file carefully. My first assumption was that this project had been compromised by a malicious package (in the <strong>package.json</strong> or <strong>package-lock.json</strong> files). That would be an easy way to trigger an exploit while hiding the payload code. Here is the process:</p><ul><li><p>Publish a malware package on <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.npmjs.com">npm</a></p></li><li><p>Add the malware package as a dependency to this project</p></li><li><p>Trigger the malware when running the project</p></li></ul><p>Unfortunately, I did not find any suspicious package. However, I did find an interesting hint.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/7276d33fa2189f52a2ce9bd60785c69445713348a0ad1b268d409d9db4ee6111.png" alt="A dependency from the package.json" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">A dependency from the package.json</figcaption></figure><p>The <strong>package.json</strong> has a dependency to the <code>fs</code> (filesystem) package, which is strange since <code>fs</code> is a built-in node module: there is no need to install it as a dependency. This was probably a mistake. But it got me thinking, the filesystem is the place to look for private keys or passwords.</p><p>A simple search for <code>fs</code> in the project revealed what I was looking for.</p><h2 id="h-step-3-the-payload" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 3: the payload</h2><p>It seems there is a <code>require(“fs”)</code> somewhere in this file…</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/9225f88e4d27930481a70bece57a8c59808e41d52118c3dbe8a04e42c9ac5acc.png" alt="?" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">?</figcaption></figure><p>I did not see it at first, but the first line is just that long. If we scroll a little bit more…</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/56443119300542b163fe473d402b65cd7bb64fc71c2b351026c6233804cf5b30.png" alt="Bingo!" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Bingo!</figcaption></figure><p><strong>Finally!</strong> This appears to be the exploit payload. This could have been innocuous minified code, but only malicious actors would conceal their code this way. Let’s analyze what it does.</p><h2 id="h-step-4-analysis" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 4: analysis</h2><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/b1491ac4fcd759f1372e310a52e70158d717ecbbb6ccea7d084bec251ed79c09.png" alt="Some of the exploit code..." blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Some of the exploit code...</figcaption></figure><p>As expected, the exploit code is obfuscated but we can still analyze it. Without executing it. To deobfuscate JS code, here are some simple steps we can take:</p><ul><li><p><strong>Pretty print:</strong> use a tool such as prettier to clean up the code. A pretty printer will format the code to reintroduce spaces and indentation where needed, to increase readability.</p></li><li><p><strong>Find the main obfuscating primitives:</strong> in this case, strings are encoded with base64. It is a quite common method to hide variable names or IP adresses.</p></li><li><p><strong>Write a script to replace strings and rename variables:</strong> input_obfuscated → script → output_deobfuscated. This allows to perform changes efficiently on the whole payload. The less manual work, the better.</p></li><li><p><strong>Do manual edits in the obfuscated source, if necessary:</strong> For example, to rename variables manually, or to change the formatting. In that case, their obfuscator tends to put multiple statements on the same line (separated by commas). I did manual edits to make the code more readable.</p></li></ul><p>After some time working on the code, it was easy to understand how the exploit works. It is triggered when the user runs the application (a Node web server) and their goal is <strong>to steal your private keys, wallets, passwords and more.</strong> Here are the original files for reference: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/morukutsu/8a309154164e3574d2563035f858fd72">Obfuscated payload</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/morukutsu/c5d7dd0c41fe561abf16e0e9c53811b4">Unobfuscated payload</a></p><p>Luckily, the obfuscation here was rather simple. They could have employed stronger techniques such as Control-flow flattening or introducing dead code.</p><p>And some code snippets from the exploit.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/be4249fc641544f7f1bc9412785db7e2ad080182255812d21d74115f51ecf94e.png" alt="Dump browser extensions data from popular browsers (Chrome, Brave, Opera...)" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Dump browser extensions data from popular browsers (Chrome, Brave, Opera...)</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/0d7f203ab17abc7349e32d34c5442643ceeb323812429d7df718833204a72a2e.png" alt="Steal your Solana private keys" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Steal your Solana private keys</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1e791938c578eabe404a6de1e05d8dd25a37931a579b33ddec1900925d591fe2.png" alt="Dump your Apple key chain" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Dump your Apple key chain</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/2f3058e2d9e39d6545c28b3b5e8a30aef1777030d6a1d654e804e89d8e0173cb.png" alt="And send all this data back home!" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">And send all this data back home!</figcaption></figure><p>This stage of the malware relies on Node to access the victim’s filesystem. Its success depends on whether or not the host gave enough permissions to Node to access restricted directories such as the home directory, and system files. Running this script with elevated privileges probably means game over.</p><h2 id="h-step-5-going-deeper" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 5: going deeper</h2><p>At this point, I had seen enough to be convinced this was an exploit attempt. However there was more: this payload had a second stage that downloaded and ran Python based malware with more elaborate features to steal user credentials.</p><p>The second stage downloads a Python program (and even downloads Python if not available on the victim machine!). Below is the full code of the second stage:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/ca543ac1446294da2b05c145629d6af741647d6c2e28b8997291f634f3935ffd.png" alt="Bootstrap for Python malware" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Bootstrap for Python malware</figcaption></figure><p>Again, this is an obfuscated payload but its structure is much simpler. The base64 encoded exploit code is decoded, and then executed. Here’s the decoded version:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f3e4d6724eceb3aa6e8b1439edab4e7c3f783a6636c342e683675c034350b558.png" alt="Stage 2, decoded" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Stage 2, decoded</figcaption></figure><p>Reference: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/morukutsu/0e1d440cfd01a77ec869f9b11cc10c6c">2nd stage payload</a></p><p>This is a client for downloading two Python based malwares. They are quite long, and analyzing them is out of the scope of this research but here are some features of the malware:</p><ul><li><p>Keylogger</p></li><li><p>Clipboard logger</p></li><li><p>Shell into the target machine: a wildcard to control the target and possibly send even stronger malware</p></li><li><p>Stealing passwords/credit cards</p></li></ul><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/c50041553eebfa7fea750f03abca1fdf5f5f61d7d11c318399e7d7850a3f5aba.png" alt="Keylogger" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Keylogger</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/26fab7cdfc44d10f2a4b8c66e7de4295e1d2f9261c9f456325f600d5e36545b3.png" alt="Stealing credit cards" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Stealing credit cards</figcaption></figure><p>Reference: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/morukutsu/6b8376c10fb9e953c0dd49452a34d343">First</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/morukutsu/31407f3c620c00db6e0b170dba217015">Second</a></p><h2 id="h-closing-words" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Closing words</h2><p>Working in the blockchain space requires extra caution to safeguard your assets.</p><p>This is especially true if you own or earn crypto. Do not run unverified Git repositories. If you must, use a virtual machine.</p><p>However, manually inspecting every file we download and run is impractical.</p><p>The community has to think about more automatic ways to detect exploits. Or make sure Node is sandboxed properly. That is also why I prefer <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://deno.com">Deno</a>’s security model, but it is not always practical to use either.</p><p>By looking for a fingerprint of the payload on Github, we can see that multiple repositories are infected. Probably forks of a similar exploit attempt.</p><p>If you think you have been exploited by this or need more details, you can reach me @moru on Farcaster.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://warpcast.com/moru">https://warpcast.com/moru</a></p><p>Hack safely!</p>]]></content:encoded>
            <author>moruu@newsletter.paragraph.com (moru)</author>
        </item>
        <item>
            <title><![CDATA[NFT pricing: luxury items]]></title>
            <link>https://paragraph.com/@moruu/nft-pricing-luxury-items</link>
            <guid>gui4qZXXyLqEcDPuUCka</guid>
            <pubDate>Wed, 23 Aug 2023 23:33:33 GMT</pubDate>
            <description><![CDATA[Average NFT prices are fairly high and their popularity in the gaming space is still niche. While there are successful blockchain games, they only appeal to a tiny segment of gamers. The most popular use-cases are:NFT art: Proof of Ownership of a digital imagePFPs: similar to the above, except they focus on group memberships and social media persona (e.g. if you own a pfp, you are part of a club)Rare in-game items: cosmetic or gameplay items/charactersTrading card games: Sorare, Gods Unchaine...]]></description>
            <content:encoded><![CDATA[<p>Average NFT prices are fairly high and their popularity in the gaming space is still niche. While there are successful blockchain games, they only appeal to a tiny segment of gamers. The most popular use-cases are:</p><ul><li><p><strong>NFT art:</strong> Proof of Ownership of a digital image</p></li><li><p><strong>PFPs:</strong> similar to the above, except they focus on group memberships and social media persona (e.g. if you own a <em>pfp</em>, you are part of a club)</p></li><li><p><strong>Rare in-game items:</strong> cosmetic or gameplay items/characters</p></li><li><p><strong>Trading card games:</strong> Sorare, Gods Unchained, etc…</p></li></ul><p>NFTs offer new ways to make (or lose) money: users hope to gain from flipping tokens on online marketplace venues. Developers use them as a way to raise money. Financial incentives are the main driver of non fungible tokens on public blockchains.</p><p>Selling digital items is not a novel idea: for instance, the Steam community market is popular and well-known compared to obscure NFT markets.</p><pre data-type="codeBlock" text="# NFT sales (28/07/2023 - http://opensea.io/category/gaming)

Rank Collection         Floor Price Volume (7d)
-----------------------------------------------
1.   HV-MTL             0.54 eth    105 eth
2.   Otherdeed Expanded 0.36 eth    84 eth
3.   Parallel Alpha     0.20 prime  70 eth
4.   Skyborne           0.02 eth    63 eth
5.   Otherside Koda     4.09 eth    56 eth
"><code># NFT sales (<span class="hljs-number">28</span><span class="hljs-operator">/</span>07<span class="hljs-operator">/</span><span class="hljs-number">2023</span> <span class="hljs-operator">-</span> http:<span class="hljs-comment">//opensea.io/category/gaming)</span>

Rank Collection         Floor Price Volume (7d)
<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>
<span class="hljs-number">1.</span>   HV<span class="hljs-operator">-</span>MTL             <span class="hljs-number">0</span><span class="hljs-number">.54</span> eth    <span class="hljs-number">105</span> eth
<span class="hljs-number">2.</span>   Otherdeed Expanded <span class="hljs-number">0</span><span class="hljs-number">.36</span> eth    <span class="hljs-number">84</span> eth
<span class="hljs-number">3.</span>   Parallel Alpha     <span class="hljs-number">0</span><span class="hljs-number">.20</span> prime  <span class="hljs-number">70</span> eth
<span class="hljs-number">4.</span>   Skyborne           <span class="hljs-number">0</span><span class="hljs-number">.02</span> eth    <span class="hljs-number">63</span> eth
<span class="hljs-number">5.</span>   Otherside Koda     <span class="hljs-number">4.09</span> eth    <span class="hljs-number">56</span> eth
</code></pre><pre data-type="codeBlock" text="# Steam market sales (28/07/2023 - http://steamfolio.com/Popular)

Rank Name                     Price   Volume (7d)
-------------------------------------------------
1.   Dreams &amp; Nightmares Case $ 1.44  $ 734 276
2.   Revolution Case          $ 1.32  $ 554 679
3.   Fracture Case            $ 0.65  $ 383 300
4.   Chroma 2 Case            $ 3.47  $ 276 333
5.   Recoil Case              $ 0.59  $ 265 461
...
7.   MOUZ (Holo) | Paris 2023 $ 16.95 $ 209 258
"><code># Steam market sales (<span class="hljs-number">28</span><span class="hljs-operator">/</span>07<span class="hljs-operator">/</span><span class="hljs-number">2023</span> <span class="hljs-operator">-</span> http:<span class="hljs-comment">//steamfolio.com/Popular)</span>

Rank Name                     Price   Volume (7d)
<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>
<span class="hljs-number">1.</span>   Dreams <span class="hljs-operator">&#x26;</span> Nightmares Case $ <span class="hljs-number">1.44</span>  $ <span class="hljs-number">734</span> <span class="hljs-number">276</span>
<span class="hljs-number">2.</span>   Revolution Case          $ <span class="hljs-number">1.32</span>  $ <span class="hljs-number">554</span> <span class="hljs-number">679</span>
<span class="hljs-number">3.</span>   Fracture Case            $ <span class="hljs-number">0</span><span class="hljs-number">.65</span>  $ <span class="hljs-number">383</span> <span class="hljs-number">300</span>
<span class="hljs-number">4.</span>   Chroma <span class="hljs-number">2</span> Case            $ <span class="hljs-number">3.47</span>  $ <span class="hljs-number">276</span> <span class="hljs-number">333</span>
<span class="hljs-number">5.</span>   Recoil Case              $ <span class="hljs-number">0</span><span class="hljs-number">.59</span>  $ <span class="hljs-number">265</span> <span class="hljs-number">461</span>
...
<span class="hljs-number">7.</span>   MOUZ (Holo) <span class="hljs-operator">|</span> Paris <span class="hljs-number">2023</span> $ <span class="hljs-number">16.95</span> $ <span class="hljs-number">209</span> <span class="hljs-number">258</span>
</code></pre><ul><li><p>NFTs trading volumes <em>seem</em> lower than Steam markets’. However NFTs are decentralized and can be traded on multiplie market places while Steam items are traded on a single centralized marketplace. A fair comparison would attempt to aggregate volumes from multiple trading venues.</p></li><li><p><strong>The main take away:</strong> the average price of a popular Steam item is lower than the floor price of a NFT gaming token.</p></li></ul><p>So NFTs tend to be sold at a higher price, akin to luxury items. Most likely because they have a higher <em>perceived</em> value. This is of course not representative of their intrinsic value: most NFTs have close to zero utility and their value is extremely inflated. Hence the typical price direction of an NFT is to drop over time to pennies.</p><p><strong>Reddit Collectible Avatars</strong> strategy (17M holders) is to sell cheap NFTs to maximize user adoption. While some unique pieces are expensive, they are following the pricing of a typical mobile game in-app purchase. Testing the technology on a large scale to familiarize users with crypto wallets is a clever strategy (→ <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dune.com/polygon_analytics/reddit-collectible-avatars">Dune</a>).</p><p>Closing thoughts:</p><ul><li><p>To aim towards mainstream adoption, most NFTs should be cheap. Luxury NFTs can be expensive, but if playing the game requires paying for an expensive token, it is not going to capture a ton of users.</p></li><li><p>NFTs creators should aim towards creating useful items, and leverage the community aspect of their collection. How to value a decentralized proof of ownership?</p><ul><li><p>Many creators design images and sell them as NFTs. What is the benefit for users compared to buying the image directly? Probably none, but no one would have bought the .jpg either. Some users just buy NFTs for fun and creators are tapping into that liquidity.</p></li><li><p>Holding a token can be used to give access to exclusive features such as in-game skins, access to a private community, shopping discounts, and more. It’s easier to value a NFT when there’s a service attached to it.</p></li></ul></li><li><p>Freedom of trading: the point of NFTs is to be able to trade them on public marketplaces with no third party. If NFTs are not tradable, then it would make more sense to implement them on a centralized server, unless it’s a feature, like tokens bound to a wallet.</p></li></ul>]]></content:encoded>
            <author>moruu@newsletter.paragraph.com (moru)</author>
        </item>
        <item>
            <title><![CDATA[Mainstream programmable cash]]></title>
            <link>https://paragraph.com/@moruu/mainstream-programmable-cash</link>
            <guid>hKvHkKBQcnFHXuYMGx9t</guid>
            <pubDate>Fri, 07 Jul 2023 00:50:33 GMT</pubDate>
            <description><![CDATA[The web evolved from static pages with text and images to dynamic content, allowing further changes after the page has been loaded in the browser. It is common nowadays to interact with other users online, publish original content or play games directly in a browser tab. Javascript, a popular scripting language, is the main technology that enabled this change. It allowed the web to go beyond static HTML/CSS and to become interactive and responsive. Similar to the web, money took different for...]]></description>
            <content:encoded><![CDATA[<p>The web evolved from static pages with text and images to dynamic content, allowing further changes after the page has been loaded in the browser. It is common nowadays to interact with other users online, publish original content or play games directly in a browser tab. Javascript, a popular scripting language, is the main technology that enabled this change. It allowed the web to go beyond static HTML/CSS and to become interactive and responsive.</p><p>Similar to the web, money took different forms throughout history, notably since the age of the internet. With digital money, customers pay online for goods and services. With the advent of blockchain technology, digital cash can now exist on public decentralized networks. Blockchain is also a less popular but viable alternative for private corporate applications, NFTs, tokenized stocks or central bank digital currencies (CBDCs).</p><p>Money had to reshape itself to evolve with technology but its usage stayed roughly the same. A (digital) cash transaction involves sending value to a third party and receive something in exchange. This transaction has to be processed by a large number of entities, whether it involves centralized currencies or cryptocurrencies.</p><p>This is a static use, reminiscent of the old web. But could we envision a future with dynamic, programmable money?</p><p>While money is not programmable by itself, most people are familiar with some forms of programmability, supported by web services and APIs. For instance, automatic cash transfers. Scheduling a transfer every month to a savings account is a form of programmable money. Or paying for a subscription service. In those two scenarios, a third party script has the permission to spend users’ money on their behalf.</p><p>Cryptocurrency is by and large used for trading, speculation and savings (<em>hodling</em>), but not really for payments. Nonetheless, Bitcoin is a thought provoking experiment that enabled many engineers to rethink about new forms money for the digital world.</p><p>In the physical world, paying with cash is second nature. In the digital world, payments require users to create accounts (or wallets), use login credentials securely and deal with KYC, 2FA authentication and more. A lot of important steps for good reasons, but quite cumbersome for low value transactions.</p><p>Programmable money is defined by two main elements: a transaction value and how it should be spent. For example, a digital bank note, signed, and issued by anybody holding a wallet. Attaching a script to money opens up many design possibilities.</p><ul><li><p>With such a system, reimbursing $10 to another party is simple: create a digital bank note that can be spent only by this person, copy and send it to them over a text message.</p></li><li><p>Want to use a paywalled API? Without creating an account, send a digital cash note to a “subscribe” API REST end point to receive an API key.</p></li><li><p>Monthly subscriptions could be <em>pushed</em> from a wallet instead of <em>pulled</em> from a bank account.</p></li></ul><p>These theoretical use cases can be implemented with public blockchains and centralized finance as well, as long as an open standard for APIs and wallets exists. CBDCs (<em>governments stablecoins</em>) might be that new open standard for traditional finance. The multiplication of “light” banking apps in the last few years shows that this is a space with large growth potential and a need for innovation.</p>]]></content:encoded>
            <author>moruu@newsletter.paragraph.com (moru)</author>
        </item>
    </channel>
</rss>