<?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>crewmateJ</title>
        <link>https://paragraph.com/@crewmate</link>
        <description>twitter: @crewmateJ</description>
        <lastBuildDate>Fri, 31 Jul 2026 02:18:56 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>crewmateJ</title>
            <url>https://storage.googleapis.com/papyrus_images/82afc80e9ef7644bc8b41378e29b24135041f5ffb4008784c59bbb86eebb33b7.jpg</url>
            <link>https://paragraph.com/@crewmate</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[The Algorithm]]></title>
            <link>https://paragraph.com/@crewmate/the-algorithm</link>
            <guid>KZoqdSmX8gRxuUXpoKz4</guid>
            <pubDate>Sat, 20 Dec 2025 18:40:44 GMT</pubDate>
            <description><![CDATA[The Algorithm is one of the most significant inventions of the 21st century and people don't talk about this enough People like to talk about crypto, robotics, and AI as the new frontiers. But besides the latent AI boom, the technology that normal people actually interact with is The Algorithm, and it has largely slipped past being a point of discussion, despite having the very powerful ability to shape the thought of the masses Information is no longer searched for, it is provided to you. In...]]></description>
            <content:encoded><![CDATA[<p>The Algorithm is one of the most significant inventions of the 21st century and people don't talk about this enough</p><p>People like to talk about crypto, robotics, and AI as the new frontiers. But besides the latent AI boom, the technology that normal people actually interact with is The Algorithm, and it has largely slipped past being a point of discussion, despite having the very powerful ability to shape the thought of the masses&nbsp;</p><p>Information is no longer searched for, it is provided to you. Instead of reading the paper to catch up on recent events, everyone has their own little newsboard. They call it For You&nbsp;</p><p>Adspace is no longer a purchasable good. There is no town message board. There is no front cover or ad break. For the most part people just scroll past sponsored ads on Twitter and Instagram</p><p>In turn, companies, government agencies, and whatever else are all fighting for attention within The Algorithm. They have to compete with anime PFPs and looksmaxxers to get their message out</p><p>It is questioned whether The Algorithm is a net good or a net bad. On one hand, free speech and information is more available than ever before. For the first time ever you can see into the life of a Mongolian goat farmer without having to ask. These days, 13 year old boys are aware of Israeli astroturfing campaigns. There are genuine success stories of people in need raising charity money through the kindness of strangers within The Algorithm</p><p>On the other hand, racism, misinformation, and "exposing" is the best way to be seen. The political bipartition is more extreme than ever. People will optimise for impressions rather than genuineness</p><p>Intelligence agencies are acutely aware of The Algorithm. They operate within it, and manipulate it where possible to their benefit. For they understand that a divided society is easier to control than a united one</p><p>When AI came in everything multiplied one hundred fold. First it was just images. Then, even videos could not be trusted. The dead internet theory will no longer be a theory. Human creators and UGC won't disappear entirely, but synthetic creators and synthetic personalities will dominate since the cost of production is way lower</p><p>Soon, The Algorithm will change from ranking content to creating it. AI has unlocked user siloed OC for the first time. Your parasocial relationship will be exclusive; no one else will get to see your favourite egirl</p><p>Real human creators will fight back by creating AI models of themselves to push content more rapidly. Influencers will "sell" you a product they have never even heard or spoken the name of</p><p>Authenticity of accounts will start becoming valuable like never before. No one wants to be sold a product by AI. There will be harsh penalties for using AI to any extent and regulation will come in for corporate businesses. The "AI" label will be the death of many accounts</p><p>The Algorithm is centralised and closed source. Meta, ByteDance, and Alphabet control upwards of 70% of the total screen time spent on The Algorithm</p><p>The ability to censor and push certain political opinions is extremely powerful. 74% of Gen Z gets their news from For You&nbsp;</p><p>You've spent three hours today inside a system you cannot see, built by people you will never meet, optimising for outcomes you did not choose. How much of what you know do you know on your own accord? How much was fed to you by For You?</p><p>The is no legislation on algorithmic transparency, yet. But maybe if there was more talk about the significance of The Algorithm, there would be</p>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/9ab3cc2aea8b56b2715377ebeaccd9f603e2e35819b0fd755eaaa3c1f8efd4d1.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[uniswap v2 and v3 explained for smoothbrains]]></title>
            <link>https://paragraph.com/@crewmate/uniswap-v2-and-v3-explained-for-smoothbrains</link>
            <guid>NTahFUmlPztGpI1qGbxa</guid>
            <pubDate>Mon, 04 Mar 2024 14:32:34 GMT</pubDate>
            <description><![CDATA[knowing how uniswap v2 and v3 pools work is mega useful and not gonna lie if youre in crypto playing onchain and cant explain them yourself — wtf — keep reading im writing this explanation for my buddy who sorta knows crypto but doesnt know enough. i tried finding a guide online but these guys writing those articles have a hard time breaking it down to the juicy stuff. theyll yap about tick pricing or mathematics but nobody gives a shit; people just wanna trade better. hopefully this super be...]]></description>
            <content:encoded><![CDATA[<p>knowing how uniswap v2 and v3 pools work is mega useful and not gonna lie if youre in crypto playing onchain and cant explain them yourself — wtf — keep reading</p><p>im writing this explanation for my buddy who sorta knows crypto but doesnt know enough. i tried finding a guide online but these guys writing those articles have a hard time breaking it down to the juicy stuff. theyll yap about tick pricing or mathematics but nobody gives a shit; people just wanna trade better. hopefully this super beginner friendly and you can send it normies so they ape our coins</p><p>im currently sitting on a plane without internet so this is off the dome but ive known this long enough i could teach it to a newborn. you might wanna fact check any numbers but the logic will all be there</p><p>quick order of what ill discuss: traditional orderbooks, AMMs, v3, v2</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/a679b5e01aa894409142c1ce6c2b1c509466eebc4d8d9218f445290f3bec0b08.png" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-traditional-orderbooks" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">traditional orderbooks:</h2><p>so you know when you buy a stock, or you buy bitcoin, who is selling it to you? is there someone else sitting at their computer at the exact same time as you? well, not exactly. maybe there is someone who placed an order 5 seconds just before you. or maybe even 1 minute before. typically its closer to 100ms. anyways, to make this exchange happen instantly for both people, we have a special type of middleman, a “market maker”. they more or less take your buy order and find someone who is also willing to sell. and obviously they sell for a little more than they buy, so this is how they profit</p><p>of course, this “market making” isnt manual, they have complex scripts running to “market make” super fast. in fact, “market making” is a whole industry. Jane Street, a trading company that “market makes”, did $8b in PROFITS in 2021. dont get any big ideas though — you dont have the IQ to participate, so keep reading and learn to shitcoin with the rest of us</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/05fab7a7628afe94c427e8090257655613aab6030093d3e231ea94dad722f86d.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-amms" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">AMMs:</h2><p>AMMs are a crypto thing, only found onchain (not found on any central exchanges). they basically remove the role of the middleman, the “market maker”. in fact AMM stands for Automated Market Maker</p><p>instead of having another person hold funds as the middle man, it is a smart contract. thats the core of it. theres heaps of advantages (and disadvantages) to having it this way. one big advantage is that because there is no middle man, its online 24/7, and you can trade things that no middleman would ever dream of trading because the thing is named something dumb like $StarlinkCockGPTInuJohnCena888</p><p>Uniswap runs on the premise of AMMs. v2 and v3 are both models of AMMs — they vary in how they work but they are both AMMs. v3 was made as an improved version of v2. v1 exists too but no one uses it. v4 also exists but idk if its live yet</p><p>now for these AMMs to work as an automatic middleman, they need to hold some funds, because if you wanted to sell $StarlinkCockGPTInuJohnCena888, you want to receive money in return at the exact time you sell. so someone has to put money in. these people are called “Liquidity Providers”, and they take a small fee for each trade that happens</p><p>to clarify on what i mean by “it is the smart contract that holds funds”, this is what i mean. the smart contract is called the “pool”. people swap one token for another in the pool. so the pool holds two types of tokens. for example, it could hold StarlinkCockGPTInuJohnCena888 and WETH. this pool would be referred to as StarlinkCockGPTInuJohnCena888/WETH</p><h2 id="h-v3" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">v3:</h2><p>the difference between v2 and v3 lies in the way that the Liquidity Providers add their funds. this is the essence of this whole explanation so pay attention NOW, i can feel your zoomer brain getting distracted already</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/afbe5bd442c46cf2db9ff10626a8e1ac75b7347239f340628a1fe8ecb1a26ef3.gif" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>this is how v3 works: if you want to add funds, you can do so in a price range. lets say you wanted to liquidity provide for StarlinkCockGPTInuJohnCena888/WETH, but you only wanted to provide funds for prices between $5 and $10. you can do that.</p><p>sidenote: if by now you still didnt get what StarlinkCockGPTInuJohnCena888/WETH is, it means that if you want to buy StarlinkCockGPTInuJohnCena888 you need to buy with WETH and if you sell StarlinkCockGPTInuJohnCena888 you receive WETH</p><p>this makes more sense when you consider pools like USDC/USDT, which in theory should always be at $1, so youd liquidity provide betwen $0.99 and $1.01. if it falls outside of 0.99–1.01, then you dont receive fees for people trading. moreover, your capital is bunched up more in a smaller range, so your contribution to the pool is more, so you receive more fees $</p><p>you can provide in multiple ranges too. with weird ranges, you can create weird trading behaviour. if people only liquidity provided in ranges $5–6 and $9–10 for StarlinkCockGPTInuJohnCena888, then the price could only exist in those ranges. itd jump straight from $6 to $9, no inbetween, it wouldnt go higher than $10 and wouldnt go less than $5</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/5fc1b0a8b777e7096ea2c97f23de567eaaf3264ef8227746203ebfc79e8af84b.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-v2" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">v2:</h2><p>v2 is far inferior because you *cant* liquidity provide in ranges. you just have to throw money in the whole entire range, from $0 to $infinity.</p><p>this greatly reduces capital efficiency. for a StarlinkCockGPTInuJohnCena888/WETH pool, you would have to provide WETH and StarlinkCockGPTInuJohnCena888 for ALL prices</p><p>another point is that with v3 there is a quirk — you can choose to provide only one of StarlinkCockGPTInuJohnCena888 and WETH in the StarlinkCockGPTInuJohnCena888/WETH pool. for example, if the price of StarlinkCockGPTInuJohnCena888 is $5, but you only want to provide in the $9–10 range, you would only need to provide StarlinkCockGPTInuJohnCena888. because well uh i cbf to explain just think about it please</p><h2 id="h-v3-examples" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">v3 examples</h2><p>here is how funds would in practice be spread for the USDC/USDT pool. “amount” is the amount of funds put in by the liquidity providers</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/77b286b2d25b092052f735b80deac4e32ed06ad368ccbb571cd3d6347186e126.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>here is how the provided funds the for StarlinkCockGPTInuJohnCena888 $5–6/$9–10 example would be spread</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/70a2cbdc3a4f46929038011a5a569e502673e80e557bd94479d3c05bd7fa5463.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><h2 id="h-trading" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">trading</h2><p>so how do you trade this? well firstly, in the hypothetical StarlinkCockGPTInuJohnCena888 scenario, you buying at $5.99 will jump the price to $9, so maybe buying there isnt a bad idea</p><p>a more practical scenario is paying attention to how shitcoin teams setup their pools. for example, in the picture below, price will move faster when it is in the range to the right, because there is not so much liquidity. so keep this in mind</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/a160a19b17ee8334a76c14ef57edcadf2df92461ae473f060c4dec9a2b89feef.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>a more broader application is: a good indication of the capabilities of a team is how they manage pools. if people are complaining about pool structure and whatnot, its probably an inexperienced team</p><p>nb: being a liquidity provider isnt free money, in fact, historically, it is a losing trade. look into “impermanent loss”. maybe ill write an easy explainer on that too. most explanations fail to not overcomplicate their explanations</p><p>so anyways thats pre much it, lmk if you had any questions, i dumbed it down a shit ton</p><p>but yeah,</p><p>retardio.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/36129e9c34081b5979b54d7ee7776c2afbc053a31e6a316400d61924f17c7e78.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/1e07e1bacaf3b7a8006523f266e13ad96e20c4cbf9f4318fd7e8e4001fb571ab.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[The post-fundamentals era of crypto investing]]></title>
            <link>https://paragraph.com/@crewmate/the-post-fundamentals-era-of-crypto-investing</link>
            <guid>o38XMkQ5yf9y4fG8y9pI</guid>
            <pubDate>Thu, 17 Aug 2023 05:25:23 GMT</pubDate>
            <description><![CDATA[So it seems there’s somewhat of a consensus that crypto is in its post-fundamentals era. That it doesn’t matter what the technology related to the token could become; because on a long enough time horizon, no token-holder has ever been rewarded for holding. The only ‘fundamentals’ a token will need is other buyers. and I’m not saying this hasn’t always been the case, it just feels more broadly realised now. There’s an acknowledgement that we can’t sell narratives of governance, potential rev-...]]></description>
            <content:encoded><![CDATA[<p>So it seems there’s somewhat of a consensus that crypto is in its post-fundamentals era. That it doesn’t matter what the technology related to the token could become; because on a long enough time horizon, no token-holder has ever been rewarded for holding. The only ‘fundamentals’ a token will need is other buyers.</p><p>and I’m not saying this hasn’t always been the case, it just feels more broadly realised now. There’s an acknowledgement that we can’t sell narratives of governance, potential rev-share, staking, and all that, because they’ve all been exhausted.</p><p>I’ve barely held any tokens with conviction since November 2021. It’s not my niche. I missed Defi Summer but I remember being partially red-pilled on the prospects of $UNI and all the Defi tokens throughout 2022, listening to old podcasts, reading old blogs, all that junk. The endgame for these tokens was supposedly to share protocol revenue and governance rights. The token holders would be partial owners of the world’s largest cross-border asset exchange.</p><p>Now almost everyone is aware the main purpose of a token is for the team and investors to cashout. So any narratives about fundamentals that are spun up are futile.</p><p>In this post-fundamentals era for crypto, coins like Pepe and HarryPotterObamicSonic10Inu are being genuinely considered on my TL as the best allocation for the next cycle. Because they contain culture. Or at least, enough culture to sell to the greater fool at a higher mcap.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/817139a8d2dbb98300ad0c051c6ea95326b04e0de1276b4d3bd5408e935a291e.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Culture is definitely important — it’s partly, if not entirely, the reason Milady is so successful. All the other PFPs are bleeding at the moment, except for the Remila eco ones. They aren’t any more fundamentally sound than any of the other PFPs, just like all the others there’s no hard asset backing them. There’s been airdrops for a while, sure, (thinking of Scatter Art, $DMT, and others here), but it’s minimal and at this point everyone can acknowledge airdrops are relatively zero sum.</p><p>Milady has been the right cultural fit for crypto for some time. In good cause from the team too, who are very much self-aware drivers of it. The tweets of the Charlotte and co and the large success of their events are testimony to this.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/REMILIONAIRE/status/1690229546304565248">https://twitter.com/REMILIONAIRE/status/1690229546304565248</a></p><p>You could even go so far to say the cultural value is ‘fundamental’ value. That people will read your tweets if you don a Remilia PFP.</p><p>Imo though, ultimately, the shitcoin cycle we are in at the moment is just another narrative. How far this narrative goes is defined by how high Hpos10i goes, or Pepe, or the next coin that hasn’t arrived yet. It could well succeed in a bigger bull when majors pump more. But to reiterate: end of the day, it is still a narrative.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/2092e89c323f96b3812e7e96e52c1a4ba8352286a80f52b370f5ad9963a88515.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Also imo, the return value on fundamentals will come eventually if crypto innovates. People will no longer end up with wool over their eyes though; we need actual fundamentals. $GMX and $RLB to name two, but they both contain long-tail protocol-level bankruptcy risk. We need more useful on-chain primitives, better self custody solutions, greater connections to real world assets, and more. Probably a lot of what we need, we don’t even know yet.</p><p>and with the return to fundamentals we might just see a rejection of the memecoins born in the post-fundamentals era.</p><p>Would highly recommend reading @CL207’s article that first made me seriously aware of the longevity of shitcoin szn.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.egirlcapital.com/writings/154108440">https://www.egirlcapital.com/writings/154108440</a>.</p><p>Perhaps my view is more optimistic, that within crypto we might see a reversion to value on fundamentals.</p><p>Thanks for reading.</p>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/fdc2d9d206d8c18f6336ac523ecf13f2aef4b5c5445cc89518d350314324ca79.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How to find Uniswap v3 TWAP using Etherscan]]></title>
            <link>https://paragraph.com/@crewmate/how-to-find-uniswap-v3-twap-using-etherscan</link>
            <guid>aTHy6qYrk2BaAPeQtCet</guid>
            <pubDate>Wed, 26 Jul 2023 05:16:10 GMT</pubDate>
            <description><![CDATA[I recently realised not everyone is aware that Uniswap v3 has a TWAP feature baked right into it. To be honest I never gave it too much thought, but was reminded of it last year when completing Damn Vulnerable Defi Challenge #14. In my opinion, the existence of the Uniswap TWAP is pretty significant. We often can’t have a Chainlink oracle for small pairs, so this TWAP may be the only decentralised option. The fact that it is a TWAP is also important in that it is more resistant to flash-loan ...]]></description>
            <content:encoded><![CDATA[<p>I recently realised not everyone is aware that Uniswap v3 has a TWAP feature baked right into it. To be honest I never gave it too much thought, but was reminded of it last year when completing <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.damnvulnerabledefi.xyz/challenges/puppet-v3/">Damn Vulnerable Defi Challenge #14</a>.</p><p>In my opinion, the existence of the Uniswap TWAP is pretty significant. We often can’t have a Chainlink oracle for small pairs, so this TWAP may be the only decentralised option. The fact that it is a TWAP is also important in that it is more resistant to flash-loan attacks than the simple spot oracle.</p><p>A use-case for the TWAP could be that it is used in a lending protocol that wants to allow permissionless loans on *any* Uniswap pair, not just whitelisted pairs. The exact implementation would need to be fleshed out more, but it is a simple high-level example.</p><p>Anyways, let’s run through how we can find the TWAP for the past hour on the FUMO/WETH pair (0x78d4e81fc84a1ce367e90936e49a74a9052137e8).</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/1c2a4ebf797a9e7064193a8b84231a5d571b4132fc08d74387193f681ed90d44.webp" alt="https://etherscan.io/address/0x78d4e81fc84a1ce367e90936e49a74a9052137e8#readContract" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">https://etherscan.io/address/0x78d4e81fc84a1ce367e90936e49a74a9052137e8#readContract</figcaption></figure><p>If we look at the `observe` function, and put in the array [0,3600], we receive data from 0 seconds ago and 1 hour ago.</p><p>The math to find the TWAP for this period is as follows:</p><p>1.0001 ** ((55811710140–55738177572) / 3600) = 7.7096 (price in WETH)</p><p>Convert to USD (<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="mailto:ETH@1898.39">ETH@1898.39</a>)</p><p>7.7096 * 1898.39 = 14635.8275</p><p>I checked Dextools and this was around the current price 👍</p><p>Current time is 2023/07/20 00:15:00 (UTC+9)</p><p>It may not always work for a longer time interval of 1 hour (3600s), because the contract can only store a limited amount of data. If you want to know the reason why, I’d suggest reading deeper into the docs. Also feel free to ask me.</p><p>That’s the high level overview of finding the TWAP. Remember, the quiddity of this is that everything I did above can all be done on-chain in real time, which is incredibly powerful.</p><p>It is worth noting there are still theoretical ways to manipulate the TWAP. An example for a larger liquidity pool:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.uniswap.org/uniswap-v3-oracles">https://blog.uniswap.org/uniswap-v3-oracles</a></p><p>In lower liquidity pools, which may be used for the permissionless lending protocol example I gave before, the implementation needs to be thorough since there will be more edge cases to consider. For example, if the lending protocol used a 10 minute TWAP, a whale could simply dump the price and hope that any vigilant buyers aren’t watching the market at the time.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/2fb16a1d87fa2743f31456f045e2fe06242f2fe4597c39369e3e1f1c97aaa592.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Class concluded, thanks for coming. Feedback and all else is appreciated — I check my Twitter DMs regularly.</p>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
        </item>
        <item>
            <title><![CDATA[Buying NFT capitulation: a theorem]]></title>
            <link>https://paragraph.com/@crewmate/buying-nft-capitulation-a-theorem</link>
            <guid>NKNDInMpSn2pkEPW7Bz1</guid>
            <pubDate>Wed, 19 Jul 2023 07:40:53 GMT</pubDate>
            <description><![CDATA[Recently we have seen record-breaking NFT liquidations, with both lenders and borrowers losing money. At some point surely the liquidations stop and price will recover to some extent. I’ve been doing some thinking — how can this be modelled, and more importantly, how can I profit off this? I have a theorem of sorts I thought of a while ago, which may or may not already formally exist. In this article I’ll try explain it and apply it to the theory of NFT capitulation. Let’s paint a scenario: B...]]></description>
            <content:encoded><![CDATA[<p>Recently we have seen record-breaking NFT liquidations, with both lenders and borrowers losing money.</p><p>At some point surely the liquidations stop and price will recover to some extent. I’ve been doing some thinking — how can this be modelled, and more importantly, how can I profit off this?</p><p>I have a theorem of sorts I thought of a while ago, which may or may not already formally exist. In this article I’ll try explain it and apply it to the theory of NFT capitulation.</p><p>Let’s paint a scenario: Bored Apes are at 40Ξ, machibigbrother.eth instantly dumps 100 apes into the Blur bidding pool, and this drags the price down to 30Ξ.</p><p>Let’s assume there has been no price-changing news, and Machi is the only seller. Assume also there are 10 passionate buyers of Bored Apes. We don’t know the prices they are willing to buy at; assume they haven’t placed any bids for us to see. Assume <strong>they will all become aware of the new price at different times</strong>. A visual example is shown below.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/61039526991590bb2dbd6ca572675fd08e672077090b380893a74257fc255b78.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Potential buyers at different times</p><p>By t=3, 9/10 buyers have become aware of the new price. If the price has moved up, it’s because some of these 9 buyers believe that 30Ξ is a reasonable entry point. Some might even believe 31Ξ, 32Ξ, 33Ξ, 34Ξ, are all good price points to buy. If this is the case, buying at t=0 was a smart decision since you could sell higher to these passionate buyers.</p><p>If none of the 9 buyers want to buy at 30Ξ, and you bought at 30Ξ, you can simply resell at breakeven or a small loss. We can see that Machi’s wallet has no more apes to sell. So whether or not we have buyers at 30Ξ, the overall expected value makes it a smart decision to buy Machi’s instant capitulation to 30Ξ.</p><p>Of course, this is grossly oversimplified in comparison to reality. For a larger population, and more randomness around when each buyer has noticed the new price, we could model the expected percentage of potential buyers (y-axis) that have seen the new price at time t (x-axis).</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/69cc4a2cf96ba74d435003ad64e16b425b9cc85b4b6c2854fa1230cad8b59f9d.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blogs.sas.com/content/iml/2015/03/04/approximate-cdf.html">https://blogs.sas.com/content/iml/2015/03/04/approximate-cdf.html</a></p><p>It may not necessarily be the curve of this lognormal CDF, but it illustrates the point.</p><p><em>At a certain time t=k, we can assume most buyers have seen the new price</em></p><p>At t=k we can assume price has adjusted accordingly, by either staying the same or moving up as described above. If we bought at t=0 it would make sense to sell at t=k.</p><p>We might be able to estimate the time <em>k</em> based on previous data, scrolling Twitter and Discord, or even just intuition.</p><p>This is still very much oversimplified, since in reality we might find new sellers at 30Ξ that were planning to hold at 40Ξ, or we might have other traders competing to buy at 30Ξ. But it is a framework that can be used, especially when it is only one wallet that is dumping the NFTs (which is often the case).</p><p>Mean-reversion is not a new phenomenon; moving averages have been used as indicators for ages. But the NFT market is still very inefficient due to a concoction of illiquidity, lack of charts, and irrational participants (this is crypto after all).</p><p>Let’s take the example of Mando (@rektmando) and OSF (@osf_rekt) dumping apes into the Blur bidding pool (February 22, 2023).</p><p>The capitulation wasn’t instant since they sold into a thick wall of Blur bids, but price spiralled shortly after they sold as bidders played hot potato to offload Apes they never wanted to buy in the first place. The graph shows a nice illustration of how it played out (pinned on the axes are the price and rough time of sale).</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/b748d579d1a65365e2ee83ee16e5ae380edfd9d905f0fdd6ac10cfbb0ac4cd9a.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Another example is GCR (@GCRClassic) selling a few hundred Miladys. Again, price and rough time of sale are pinned. The bottom only a few hours after he sold was noticeable since he was selling in multiple transactions over an hour or so. Although he still had some Miladys left, the selling transactions stopped.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/43ce0267f94a9827202ccb93d555e51e58abd7287a890587a01bc1732dbded36.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>Anyways, food for thought, I’m sure this theorem or a variation has a name somewhere. Keep it in mind and don’t be afraid to buy ugly JPEGs to sell upon mean-reversion.</p>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
        </item>
        <item>
            <title><![CDATA[Picking Up Pennies from Uninitialised Implementation Contracts]]></title>
            <link>https://paragraph.com/@crewmate/picking-up-pennies-from-uninitialised-implementation-contracts</link>
            <guid>cRyONo2AjofmzWALtNqq</guid>
            <pubDate>Wed, 19 Jul 2023 07:39:32 GMT</pubDate>
            <description><![CDATA[crewmateJCoinsBenchNB: article was written in Feb 2023, albeit published in May 2023 A post by 0xCygaar a few weeks ago explained how he took control of the Qzuki implementation contract. Only a few days later I saw he took control of another NFT project’s implementation contract! It got me thinking… could I do this myself?Proxies?If you don’t know how proxy contracts work, this article may not make sense — I would suggest reading up on them quickly, specifically the Transparent Upgradeable P...]]></description>
            <content:encoded><![CDATA[<figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/d0029e4c445e1e18f686e748b88567554a3166ce8f1267f72f1c10fca67a7b6c.png" alt="crewmateJ" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">crewmateJ</figcaption></figure><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/785b74c6f17e80eacc3b7e09b39e33dec58dc50716b20697b17d194df72dcfdb.jpg" alt="CoinsBench" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">CoinsBench</figcaption></figure><p><strong>NB: article was written in Feb 2023, albeit published in May 2023</strong></p><p>A <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/0xCygaar/status/1620496240445378561">post</a> by 0xCygaar a few weeks ago explained how he took control of the Qzuki implementation contract. Only a few days later I saw he took control of <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/0xCygaar/status/1621417995905167360">another</a> NFT project’s implementation contract! It got me thinking… could I do this myself?</p><h2 id="h-proxies" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Proxies?</h2><p>If you don’t know how proxy contracts work, this article may not make sense — I would suggest reading up on them quickly, specifically the <code>Transparent Upgradeable Proxy</code> pattern.</p><p>If you can’t be bothered, just use the diagram below for reference:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.certik.com/resources/blog/FnfYrOCsy3MG9s9gixfbJ-upgradeable-proxy-contract-security-best-practices">https://www.certik.com/resources/blog/FnfYrOCsy3MG9s9gixfbJ-upgradeable-proxy-contract-security-best-practices</a></p><p>In essence, proxies exist so the user only ever has to interact with the <code>Proxy</code> contract, but devs can still change the <code>Implementation</code> contract. The devs can ‘upgrade’ the contract logic, without rocking the (figurative) boat of the whole system.</p><p>Most on-chain participants would have interacted with a proxy pattern before, and may even recognise the name <code>Transparent Upgradeable Proxy</code> from Etherscan’s labels:</p><h2 id="h-back-to-my-question" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Back to my question</h2><p>Could I find any implementation contracts to take ownership of? Over the next few days, I checked every Transparent Upgradeable Proxy contract I saw.</p><p>To my surprise, it was very common for projects to forget to initialise their implementation contract. If a contract is uninitialised, it often means *anyone *can call the <code>initialize()</code>function and take ownership.</p><p>While it’s not a very high-risk mistake, it could* *have negative effects for users. If an attacker took control over the implementation contract, they could deploy some phishing attempts under the guise of the original contract deployer. 0xCygaar’s post talks a bit about this.</p><p>Another problem is, if users accidentally send ETH to the implementation contract, someone else may be able to yoink it.</p><p>Yoinkage is exactly what I have attempted.</p><p>I searched the Ethereum mainnet for Transparent Upgradeable Proxies and their implementation contract, to see if any projects have left ETH in uninitialised implementation addresses.</p><h2 id="h-the-process" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Process</h2><ul><li><p>scan the chain for the <code>Upgraded(address implementation)</code> event, the hash is:</p></li></ul><blockquote><p>0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b</p></blockquote><ul><li><p>Etherscan’s API allows you to query events in a specified block range regardless of contract address. Below is what the Upgraded event typically looks like. The implementation address is in topics[1] (it’s padded with 0s).</p></li></ul><ul><li><p>once I had the implementation addresses I filtered by ETH balance and token balances</p></li><li><p>If a contract was uninitialised and contained ETH, I’d check for the <code>initialize()</code> and <code>withdraw()</code> functions, then try call them. Some contracts also have a <code>withdrawToken()</code> function.</p></li></ul><p>You can often tell a contract is uninitialised if the <code>owner</code> returns 0x00..00.</p><h2 id="h-in-summary" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">In Summary</h2><p>Well, all that and I only got 0.06 ETH ($100) from one contract -_-</p><p>There were a few unverified contracts with $30–40 in them but after gas I’m sure it wouldn’t be worth it.</p><p>Some things I did find:</p><ul><li><p>The “Blur Pool contract <code>0x17584a148d27ac5d06d87771464dacbaf625ce45</code> has 0.0205 ETH stuck in it but they used the correct measures to prevent anyone from initialising the contract:</p></li></ul><ul><li><p>The Covan Cats implementation contract <code>0x443df53788d483a33a2aaeb8e6f02b78752090c2</code> has 0.55e stuck in it o_o</p></li><li><p>This contract here is uninitialised with 0.05e and 50 DAI, but there doesn’t seem to be a way to initialise it… <code>0x939bde6c3495f8b5caa9b9ededec1bc63b35c1fe</code>.</p></li></ul><p>That’s it, thanks for reading!</p><p>I hope this inspired some teams to initialise their implementation contracts, so if users accidentally send ETH to them, that ETH can be easily recovered.</p><p>Oh, and I’ve already checked most other major EVM chains for yoinkage, I found nothing ://</p>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
        </item>
        <item>
            <title><![CDATA[Replay Attacks, Self-destructing Contracts, and Ethereum’s Memory Layout: What I Learned From Completing Damn Vulnerable Defi Challenge #13 ‘Wallet Mining’]]></title>
            <link>https://paragraph.com/@crewmate/replay-attacks-self-destructing-contracts-and-ethereum-s-memory-layout-what-i-learned-from-completing-damn-vulnerable-defi-challenge-13-wallet-mining</link>
            <guid>T0QaaIGaNsERm6GBj9CU</guid>
            <pubDate>Wed, 19 Jul 2023 07:34:50 GMT</pubDate>
            <description><![CDATA[Since early December, I have been obsessed with the challenges over at damnvulnerabledefi.xyz . They have taken my knowledge of DeFi and smart contracts to the next level, to say the least. After I completed the first twelve challenges by early January, I was very happy to hear that @tinchoabatte had just released three more challenges! Challenge #13 was most definitely the hardest, and it took me about a week to finish. Here is how I completed it, and what I learnt in the process. Keep in mi...]]></description>
            <content:encoded><![CDATA[<br><p>Since early December, I have been obsessed with the challenges over at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="http://damnvulnerabledefi.xyz/">damnvulnerabledefi.xyz</a> . They have taken my knowledge of DeFi and smart contracts to the next level, to say the least. After I completed the first twelve challenges by early January, I was very happy to hear that @<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/tinchoabbate">tinchoabatte</a> had just released three more challenges!</p><p>Challenge #13 was most definitely the hardest, and it took me about a week to finish. Here is how I completed it, and what I learnt in the process. Keep in mind, many of the concepts used to complete this challenge I was learning for the first time. For more experienced blockchain developers, I imagine this challenge could be completed in 1–2 hours.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/4b449f99ee52816bb34866e7d73fd59925362854f08ff9eed123f22f43c7d406.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.damnvulnerabledefi.xyz/challenges/wallet-mining/">https://www.damnvulnerabledefi.xyz/challenges/wallet-mining/</a></p><p>For context, I had already completed Challenge 11 so I had a decent understanding of the Gnosis contracts already. The most helpful resource I found was <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/watch?v=_2ZJ5HBEfUk&amp;t=1854s&amp;ab_channel=dearesthui">this video</a>.</p><p>After reading the problem, I knew the first and most obvious step would be to deploy the Gnosis contracts onto this new chain. I had just recently read <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/0xfoobar">@0xfoobar</a>’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://0xfoobar.substack.com/p/vanity-addresses">article on vanity addresses</a>, so I was aware that it was possible to replicate contract addresses on new chains.</p><p>Here is a snippet from the article that I used as my first lead:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/f5bffd77afe14607321aa730fafb3db0056cab89d4c1267dfdcca87788b833b6.webp" alt="" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>The article explains that smart contract addresses can be kept consistent across chains by using CREATE2 and keeping the ‘sender’ variable constant by deploying via a smart contract. I was able to quickly disregard this thesis through Etherscan, by seeing that the deployments for the Gnosis contracts 0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F and 0x76E2cFc1F5Fa8F6a5b3fC4c8F4788F0116861F9B were performed via an EOA, not a contract.</p><p>The article also nods at keyless transactions, which was another rabbit-hole I went down by reading <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c">this article</a>. This theory was also disregarded since the EOA that deployed each contract had completed other transactions.</p><p>I was at a bit of a loss so I headed to the Github repo for clues, where I found this:</p><p><em>“Also, the scenario presented in the challenge is quite similar to an issue that happened not so long ago.”</em></p><p>The first thing I thought of was the Optimism hack in June last year, where 20 million OP tokens were sent to the wrong address but recovered by a white-hat through a replay attack. But I thought replay attacks were a thing of the past post EIP-155?</p><p>As it turns out, a transaction can be replicated across chains post EIP-155 if the transaction is submitted with a chain ID of zero (instead of the typical 1 for mainnet). I couldn’t find the chain ID on Etherscan but was able to quickly find it using this:</p><pre data-type="codeBlock" text="const tx = await provider.getTransaction(TX_HASH);
console.log(&apos;Chain ID is: &apos;, tx.chainId);
"><code>const <span class="hljs-built_in">tx</span> <span class="hljs-operator">=</span> await provider.getTransaction(TX_HASH);
console.log(<span class="hljs-string">'Chain ID is: '</span>, <span class="hljs-built_in">tx</span>.chainId);
</code></pre><p>For both deployment transactions 0x06d2fa464546e99d2147e1fc997ddb624cec9c8c5e25a050cc381ee8a384eed3 and 0x75a42f240d229518979199f56cd7c82e4fc1f1a20ad9a4864c635354b4a34261 the chain ID was zero. These transactions were sent by 0x1aa7451dd11b8cb16ac089ed7fe05efa00100a6a and had a nonce of 0 and 2 respectively, so I had to check the chain ID of the transaction with nonce 1 on that EOA — which I found also had a chain ID of 0.</p><p>With this knowledge, I knew I could replicate these transactions even though I didn’t have the private key to the Gnosis Safe Deployer wallet 0x1aa7451dd11b8cb16ac089ed7fe05efa00100a6a.</p><p>So I had the first hurdle out of the way, now I needed to complete the rest of the challenge. The fact that the challenge name was ‘Wallet Mining’ and that 20 million tokens were stored in an empty address 0x9b6fb606a9f5789444c17768c6dfcf2f83563801 was enough of a hint for me.</p><p>The solution is that the 43rd Gnosis Safe that gets deployed via the WalletDeployer contract is this address. By making the wallet a 1-of-1 multi-sig and setting myself as the only owner, I could safely execute a transfer of the tokens out of this wallet. In fact, it even didn’t matter who the owners of the multi-sig were since I could execute the transfer within the ‘setup’ function of the MasterCopy contract.</p><pre data-type="codeBlock" text="/// Source: https://etherscan.deth.net/address/0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F

/// @dev Setup function sets initial storage of contract.
/// @param _owners List of Safe owners.
/// @param _threshold Number of required confirmations for a Safe transaction.
/// @param to Contract address for optional delegate call.
/// @param data Data payload for optional delegate call.
/// @param fallbackHandler Handler for fallback calls to this contract
/// @param paymentToken Token that should be used for the payment (0 is ETH)
/// @param payment Value that should be paid
/// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)
function setup(
    address[] calldata _owners,
    uint256 _threshold,
    address to,
    bytes calldata data,
    address fallbackHandler,
    address paymentToken,
    uint256 payment,
    address payable paymentReceiver
) external {
  /// ...
  /// ...
  /// ...
}
"><code><span class="hljs-comment">/// Source: https://etherscan.deth.net/address/0x34CfAC646f301356fAa8B21e94227e3583Fe3F5F</span>

<span class="hljs-comment">/// @dev Setup function sets initial storage of contract.</span>
<span class="hljs-comment">/// @param _owners List of Safe owners.</span>
<span class="hljs-comment">/// @param _threshold Number of required confirmations for a Safe transaction.</span>
<span class="hljs-comment">/// @param to Contract address for optional delegate call.</span>
<span class="hljs-comment">/// @param data Data payload for optional delegate call.</span>
<span class="hljs-comment">/// @param fallbackHandler Handler for fallback calls to this contract</span>
<span class="hljs-comment">/// @param paymentToken Token that should be used for the payment (0 is ETH)</span>
<span class="hljs-comment">/// @param payment Value that should be paid</span>
<span class="hljs-comment">/// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setup</span>(<span class="hljs-params">
    <span class="hljs-keyword">address</span>[] <span class="hljs-keyword">calldata</span> _owners,
    <span class="hljs-keyword">uint256</span> _threshold,
    <span class="hljs-keyword">address</span> to,
    <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">calldata</span> data,
    <span class="hljs-keyword">address</span> fallbackHandler,
    <span class="hljs-keyword">address</span> paymentToken,
    <span class="hljs-keyword">uint256</span> payment,
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">payable</span> paymentReceiver
</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> </span>{
  <span class="hljs-comment">/// ...</span>
  <span class="hljs-comment">/// ...</span>
  <span class="hljs-comment">/// ...</span>
}
</code></pre><p>So I had the 20 million tokens, but there were still some tokens in the WalletDeployer contract — 43 to be exact. I probably should have called it a day here and walked home with the 20 million tokens I had already stolen. But I wanted to complete the challenge!</p><p>I spent at least two days reading all about Solidity’s low-level assembly language just to understand the function in <code>WalletDeployer.sol</code> — part of this was learning the official memory layout for Solidity, through the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.soliditylang.org/en/v0.8.4/internals/layout_in_memory.html">docs</a>.</p><pre data-type="codeBlock" text="// TODO(0xth3g450pt1m1z0r) put some comments
function can(address u, address a) public view returns (bool) {
    assembly { 
        let m := sload(0)
        if iszero(extcodesize(m)) {return(0, 0)}
        let p := mload(0x40)
        mstore(0x40,add(p,0x44))
        mstore(p,shl(0xe0,0x4538c4eb))
        mstore(add(p,0x04),u)
        mstore(add(p,0x24),a)
        if iszero(staticcall(gas(),m,p,0x44,p,0x20)) {return(0,0)} 
        if and(not(iszero(returndatasize())), iszero(mload(p))) {return(0,0)}
    }
    return true;
}
"><code><span class="hljs-comment">// TODO(0xth3g450pt1m1z0r) put some comments</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">can</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> u, <span class="hljs-keyword">address</span> a</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">view</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">bool</span></span>) </span>{
    <span class="hljs-keyword">assembly</span> { 
        <span class="hljs-keyword">let</span> m <span class="hljs-operator">:=</span> <span class="hljs-built_in">sload</span>(<span class="hljs-number">0</span>)
        <span class="hljs-keyword">if</span> <span class="hljs-built_in">iszero</span>(<span class="hljs-built_in">extcodesize</span>(m)) {<span class="hljs-keyword">return</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>)}
        <span class="hljs-keyword">let</span> p <span class="hljs-operator">:=</span> <span class="hljs-built_in">mload</span>(<span class="hljs-number">0x40</span>)
        <span class="hljs-built_in">mstore</span>(<span class="hljs-number">0x40</span>,<span class="hljs-built_in">add</span>(p,<span class="hljs-number">0x44</span>))
        <span class="hljs-built_in">mstore</span>(p,<span class="hljs-built_in">shl</span>(<span class="hljs-number">0xe0</span>,<span class="hljs-number">0x4538c4eb</span>))
        <span class="hljs-built_in">mstore</span>(<span class="hljs-built_in">add</span>(p,<span class="hljs-number">0x04</span>),u)
        <span class="hljs-built_in">mstore</span>(<span class="hljs-built_in">add</span>(p,<span class="hljs-number">0x24</span>),a)
        <span class="hljs-keyword">if</span> <span class="hljs-built_in">iszero</span>(<span class="hljs-built_in">staticcall</span>(<span class="hljs-built_in">gas</span>(),m,p,<span class="hljs-number">0x44</span>,p,<span class="hljs-number">0x20</span>)) {<span class="hljs-keyword">return</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>)} 
        <span class="hljs-keyword">if</span> <span class="hljs-built_in">and</span>(<span class="hljs-built_in">not</span>(<span class="hljs-built_in">iszero</span>(<span class="hljs-built_in">returndatasize</span>())), <span class="hljs-built_in">iszero</span>(<span class="hljs-built_in">mload</span>(p))) {<span class="hljs-keyword">return</span>(<span class="hljs-number">0</span>,<span class="hljs-number">0</span>)}
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre><p>Even after understanding what is going on here, I couldn’t see exactly where the exploit was.</p><p>I did have some leads though. The problem explicitly mentions that <code>AuthorizerUpgradeable.sol</code> uses an upgradeable mechanism — the UUPS proxy pattern. I recalled reading a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/0xCygaar/status/1620496240445378561">post by @0xCygaar</a> about how he took control of the Qzuki implementation contract. However Qzuki used the Transparent Upgradeable Proxy pattern. I also remembered reading in the comments of this post that a vulnerability in UUPS proxies is that an attacker can take ownership, upgrade, then call a self-destruct function on the implementation contract.</p><p>Thinking about this, we can see how all the checks in the assembly block can be passed. I needn’t explain all them here, but if you review <code>Proxy.sol</code>you may be able to understand how this is the case.</p><p>So that’s about it, once we know we can force the ‘can’ function to return true, we can be payed 1 token for each deployment we make. Deploy 43 more Gnosis Safes, and we have officially taken all the tokens.</p><p>Ideally we would do the whole self-destruct-the-implementation-contract bit first, so that we only had to deploy a total of 43 safes rather than 86, but this was simply the order I found the solution.</p><p>Relevant files I used for the solution can be found at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/crewmateJ/damn-vulnerable-defi-13">https://github.com/crewmateJ/damn-vulnerable-defi-13</a></p>]]></content:encoded>
            <author>crewmate@newsletter.paragraph.com (crewmateJ)</author>
        </item>
    </channel>
</rss>