<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joshua Ofamba</title>
    <description>The latest articles on DEV Community by Joshua Ofamba (@josh_the_dev).</description>
    <link>https://dev.to/josh_the_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3849227%2F15781672-148f-47c4-b352-e24d65f2e71e.jpg</url>
      <title>DEV Community: Joshua Ofamba</title>
      <link>https://dev.to/josh_the_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josh_the_dev"/>
    <language>en</language>
    <item>
      <title>I Built a Website Without Paying for Hosting—Here’s What Happened</title>
      <dc:creator>Joshua Ofamba</dc:creator>
      <pubDate>Wed, 01 Apr 2026 12:31:56 +0000</pubDate>
      <link>https://dev.to/josh_the_dev/you-dont-need-a-hosting-provider-to-set-up-your-website-i-tried-it-ga4</link>
      <guid>https://dev.to/josh_the_dev/you-dont-need-a-hosting-provider-to-set-up-your-website-i-tried-it-ga4</guid>
      <description>&lt;p&gt;&lt;em&gt;Most people assume a website requires a hosting bill. That assumption is wrong. IPFS lets you publish a real, custom-domain website on a peer-to-peer network — for free.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AD6PVX6mdJCNmezoZ" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AD6PVX6mdJCNmezoZ" alt="Depiction of a distributed network" width="1024" height="683"&gt;&lt;/a&gt;&lt;br&gt;Photo by NASA on Unsplash
  &lt;/p&gt;

&lt;p&gt;If you have ever built a personal site, portfolio, or small project, you know the drill: pick a host, enter a card number, wait for the bill. It feels like the cost of doing business. It isn’t.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://ipfs.tech" rel="noopener noreferrer"&gt;InterPlanetary File System (IPFS)&lt;/a&gt; is a peer-to-peer protocol that lets you publish static websites without leasing space on anyone’s server. This article walks you through building a site, publishing it to IPFS, and pointing a real domain at it — no hosting contract required.&lt;/p&gt;

&lt;p&gt;Let’s see how we can achieve this:&lt;/p&gt;

&lt;h3&gt;
  
  
  How IPFS Works for Websites
&lt;/h3&gt;

&lt;p&gt;Traditional hosting points a URL at a specific server. If that server goes down, your page goes with it. IPFS flips this centralized model to a peer-to-peer(P2P) model.&lt;/p&gt;

&lt;p&gt;When you add a file to the IPFS network, it receives a &lt;strong&gt;Content Identifier (CID).&lt;/strong&gt; This is a cryptographic hash derived from the file’s contents. Any node(peer) holding your file can serve it, so there is no single point of failure and no single bill to pay.&lt;/p&gt;

&lt;p&gt;The trade-off is that IPFS only works with &lt;strong&gt;static sites&lt;/strong&gt;  — HTML, CSS, JavaScript, and assets like images or videos. Dynamic server-side languages like PHP or Python are not supported. For server-side functionality, you still need traditional infrastructure. If your project only &lt;a href="https://thenewstack.io/introduction-to-frontend-development/" rel="noopener noreferrer"&gt;&lt;strong&gt;runs on the frontend&lt;/strong&gt;&lt;/a&gt;, then you’re good to work with IPFS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Your Site
&lt;/h3&gt;

&lt;p&gt;First, let’s set up a local IPFS node. You can follow &lt;a href="https://www.makeuseof.com/how-to-set-up-and-use-ipfs/" rel="noopener noreferrer"&gt;this article&lt;/a&gt; on how to download and install one.&lt;/p&gt;

&lt;p&gt;IPFS doesn’t care how you author your content. You can write plain HTML, use a static generator like Hugo or Eleventy, or even scaffold a React app.&lt;/p&gt;

&lt;p&gt;Here is a minimal HTML file to get you started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My IPFS Site&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"./style.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello from IPFS&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the content above and place it in a file named &lt;code&gt;index.html&lt;/code&gt;. Now, open your IPFS node and navigate to the &lt;code&gt;Files&lt;/code&gt; page. Next, click the &lt;strong&gt;Import&lt;/strong&gt; button, choose the &lt;strong&gt;File&lt;/strong&gt; option, and upload the &lt;code&gt;index.html&lt;/code&gt; file created earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AjCxIts_Tou0QzAJ_244XlQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AjCxIts_Tou0QzAJ_244XlQ.png" alt="Upload file to IPFS" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the upload, click on the three dots on the file and choose &lt;strong&gt;Share link&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ACWLaZzBEm4I0sXy5HkM3RQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ACWLaZzBEm4I0sXy5HkM3RQ.png" alt="URL to IPFS site" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it. You should have a link that resembles this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//bafybeifkygjhioi37knmgvlpl5lnbxo6lphn76raedrvsskihcn4sfwguq.ipfs.dweb.link?filename=index.html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can paste this link into the browser to view your deployed site. For the first time, it may take about a minute for it to load. You should then see a page like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw33sy32p9z19dn82tyfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw33sy32p9z19dn82tyfm.png" alt="Sample IPFS web page" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  The Redeployment Problem
&lt;/h4&gt;

&lt;p&gt;Every time you change a file and re-import it, IPFS generates a brand-new CID. Anyone who bookmarked or linked to your old CID now hits a dead end. For a site you plan to update, this is a real problem.&lt;/p&gt;

&lt;p&gt;IPFS solves this using &lt;strong&gt;IPNS (InterPlanetary Name System)&lt;/strong&gt;, which is a mutable naming system that always points to your latest CID. Think of it as a forwarding address: you publish once to an IPNS key, and it redirects to whatever CID you tell it to.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://docs.ipfs.tech/concepts/ipns/" rel="noopener noreferrer"&gt;IPFS documentation on IPNS&lt;/a&gt; explains more about how to generate and publish IPNS keys.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep Your Site Online: Three Approaches
&lt;/h3&gt;

&lt;p&gt;Importing a folder into IPFS Desktop makes your content available from your machine. But when your laptop closes, so does your site. You have three options for keeping it live.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Self-Hosting
&lt;/h4&gt;

&lt;p&gt;Self-hosting means running your own IPFS node continuously to keep your content available on the network. If you have a home server or a VPS, you can keep an IPFS node running there and pin your CID. &lt;strong&gt;Pinning means that your IPFS node permanently stores the imported data.&lt;/strong&gt; By default, IPFS treats your uploads as temporary, so you have to make them permanent by pinning.&lt;/p&gt;

&lt;p&gt;For production use, self-hosting may not be practical due to challenges associated with managing your infrastructure, e.g., during a downtime.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Pinning Service
&lt;/h4&gt;

&lt;p&gt;Pinning services handle persistence for you by storing and serving your IPFS content on always-on infrastructure. After uploading your site, the service pins your CID.&lt;/p&gt;

&lt;p&gt;Popular providers like &lt;a href="https://www.pinata.cloud/" rel="noopener noreferrer"&gt;Pinata&lt;/a&gt; and &lt;a href="https://filebase.com/" rel="noopener noreferrer"&gt;Filebase&lt;/a&gt; provide 1GB of free storage to try out their services. They typically offer APIs, dashboards, and SDKs for managing uploads and pins. This is the most common approach for developers who want reliability without maintaining infrastructure.&lt;/p&gt;

&lt;p&gt;The trade-off is partial dependence on third-party services, though your data remains content-addressed and accessible across the IPFS network.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Automated Deployment via GitHub Actions
&lt;/h4&gt;

&lt;p&gt;This approach integrates IPFS deployment into your CI/CD pipeline. Whenever you push changes to your repository, a workflow automatically builds your site and uploads it to IPFS using a pinning provider.&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://docs.ipfs.tech/how-to/websites-on-ipfs/deploy-github-action/" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt;, you can define workflows that trigger on commits, generate a new CID, and optionally update DNS records (e.g., via IPNS or DNSLink). This ensures your IPFS-hosted site stays in sync with your codebase without manual intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up a Custom Domain
&lt;/h3&gt;

&lt;p&gt;Sharing a raw gateway URL works, but &lt;code&gt;ipfs.io/ipfs/Qm…&lt;/code&gt; is not something visitors will remember or trust. You can instead link your IPFS URL to standard domain names like &lt;code&gt;example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can login to your domain registrar’s dashboard, find the domain’s redirect (or forwarding) settings, and point it to your IPFS gateway URL. After this, your users will now be able to access the site using the domain name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;IPFS proves that hosting isn’t a requirement; it’s a choice. You can publish a real, custom-domain website with no hosting bill.&lt;/p&gt;

&lt;p&gt;There are still some trade-offs, but the technology is improving. The decentralized web is the future.&lt;/p&gt;

</description>
      <category>website</category>
      <category>internet</category>
      <category>ipfs</category>
      <category>decentralized</category>
    </item>
    <item>
      <title>the FFmpeg example really hit home. i personally didn't know that the ffmpeg team writes *assembly code by hand* to give us as much as x50 speed up compared to a high-level approach!!</title>
      <dc:creator>Joshua Ofamba</dc:creator>
      <pubDate>Mon, 30 Mar 2026 08:40:12 +0000</pubDate>
      <link>https://dev.to/josh_the_dev/the-ffmpeg-example-really-hit-home-i-personally-didnt-know-that-the-ffmpeg-team-writes-assembly-2c9e</link>
      <guid>https://dev.to/josh_the_dev/the-ffmpeg-example-really-hit-home-i-personally-didnt-know-that-the-ffmpeg-team-writes-assembly-2c9e</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/josh_the_dev/why-you-should-contribute-to-open-source-even-as-a-beginner-43nk" class="crayons-story__hidden-navigation-link"&gt;I Tried Contributing to Open Source—And Now I Understand Why People Do It for Free&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/josh_the_dev" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3849227%2F15781672-148f-47c4-b352-e24d65f2e71e.jpg" alt="josh_the_dev profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/josh_the_dev" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Joshua Ofamba
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Joshua Ofamba
                
              
              &lt;div id="story-author-preview-content-3424999" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/josh_the_dev" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3849227%2F15781672-148f-47c4-b352-e24d65f2e71e.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Joshua Ofamba&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/josh_the_dev/why-you-should-contribute-to-open-source-even-as-a-beginner-43nk" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 30&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/josh_the_dev/why-you-should-contribute-to-open-source-even-as-a-beginner-43nk" id="article-link-3424999"&gt;
          I Tried Contributing to Open Source—And Now I Understand Why People Do It for Free
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/josh_the_dev/why-you-should-contribute-to-open-source-even-as-a-beginner-43nk#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>opensource</category>
    </item>
    <item>
      <title>I Tried Contributing to Open Source—And Now I Understand Why People Do It for Free</title>
      <dc:creator>Joshua Ofamba</dc:creator>
      <pubDate>Thu, 26 Mar 2026 09:05:26 +0000</pubDate>
      <link>https://dev.to/josh_the_dev/why-you-should-contribute-to-open-source-even-as-a-beginner-43nk</link>
      <guid>https://dev.to/josh_the_dev/why-you-should-contribute-to-open-source-even-as-a-beginner-43nk</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AUUPxYmpJ7MxFUBBP" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AUUPxYmpJ7MxFUBBP" alt="Home page of a GitHub project" width="1024" height="585"&gt;&lt;/a&gt;&lt;br&gt;Photo by Luke Chesser on Unsplash.
  &lt;/p&gt;

&lt;p&gt;Most of the software I use every day is free. Not “free trial” free, but fully open, maintained by people who aren’t getting paid for it. For a long time, that didn’t make sense to me. Why would skilled developers spend hours writing, reviewing, and maintaining code for strangers on the internet?&lt;/p&gt;

&lt;p&gt;So I decided to find out for myself.&lt;/p&gt;

&lt;p&gt;I picked a project (OWASP), set up my environment, and attempted my first contribution. I expected it to be complicated, maybe even frustrating. And it was. But what surprised me wasn’t just the process—it was what I learned about why people keep showing up and contributing, even when there’s no paycheck involved.&lt;/p&gt;

&lt;p&gt;Below, I'll share with you the things I learned from following open-source projects on social media, joining their communities, and ultimately making my first contribution. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Your Work Gets Recognized, Permanently
&lt;/h3&gt;

&lt;p&gt;One of the most underrated perks of open-source contribution is recognition that goes far deeper than a LinkedIn endorsement. When you contribute to a public repository, that work is attributed to you on platforms where employers and collaborators are actively looking.&lt;/p&gt;

&lt;p&gt;GitHub stars are one of the simplest and most visible signals of real-world impact. If a project you’ve built or contributed to has hundreds of stars, it shows that people are actually finding it useful—something a personal portfolio alone can’t easily demonstrate.&lt;/p&gt;

&lt;p&gt;On top of that, tools like &lt;a href="https://gitpoap.io/" rel="noopener noreferrer"&gt;GitPOAP⁠&lt;/a&gt; take recognition a step further by turning your merged pull requests into verifiable, shareable records tied directly to your GitHub identity. These show up as &lt;strong&gt;digital badges&lt;/strong&gt; linked to specific contributions or events, making it easier to demonstrate not just &lt;em&gt;what&lt;/em&gt; you’ve worked on, but &lt;em&gt;where&lt;/em&gt; and how you’ve participated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A77fJvmtWSZz6m8B0" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A77fJvmtWSZz6m8B0" alt="Polar bear in the Arctic" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;The GitHub Arctic Code Vault stores a snapshot of the most used public repositories on an archival film beneath the ice-cold rocks in Svalbard, Norway.
  &lt;/p&gt;

&lt;p&gt;The most dramatic example of open source recognition, however, is the &lt;a href="https://archiveprogram.github.com/arctic-vault/" rel="noopener noreferrer"&gt;GitHub Arctic Code Vault&lt;/a&gt;. On February 2, 2020, GitHub captured a snapshot of every active public repository and encoded it onto archival film designed to last 1,000 years, then stored it beneath a mountain in Svalbard, Norway. If you contributed to any qualifying project before that date, your name is literally preserved in permafrost. GitHub marks this on contributor profiles with the Arctic Code Vault badge, visible to anyone who views your profile.&lt;/p&gt;

&lt;p&gt;Contributing to open source doesn’t just build a resume. It builds a verifiable, public, and in some cases permanent record of who you are as a developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. It Can Be a Hard Career Requirement
&lt;/h3&gt;

&lt;p&gt;I used to think open-source was something you did after you got good. In reality, it’s often how you prove you’re good in the first place.&lt;/p&gt;

&lt;p&gt;When I started exploring opportunities, especially in web3, &lt;em&gt;I kept running into the same pattern: people who were getting internships, grants, or early roles almost always had some form of open-source contribution.&lt;/em&gt; Not massive projects. Just evidence that they had worked in public.&lt;/p&gt;

&lt;p&gt;For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Some internship programs (&lt;a href="https://owasp.org/www-community/initiatives/gsoc/gsoc2026ideas" rel="noopener noreferrer"&gt;like those under OWASP&lt;/a&gt;) explicitly prioritize applicants who have made public contributions before&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In many web3 communities like Ethereum, grants are normally given out to applicants that have open-source contributions in the ecosystem &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when I made my first few contributions, I realized that employers weren't asking for perfection. All they needed was proof that you can integrate into their current development workflow. &lt;/p&gt;

&lt;p&gt;So while open source might look like “free work” on the surface, in practice it’s closer to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a public portfolio&lt;/li&gt;
&lt;li&gt;a collaborative interview&lt;/li&gt;
&lt;li&gt;and, in many cases, a gateway into opportunities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Even if you’re not targeting open-source-heavy roles, the habits you build while contributing are valuable. They include navigating large codebases, writing &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;clear commit messages&lt;/a&gt;, and working asynchronously across time zones.&lt;/strong&gt; These are professional skills most bootcamps and universities do not teach.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Projects You Use Need You More Than You Think
&lt;/h3&gt;

&lt;p&gt;There’s a tension at the heart of open source that most users never see. A handful of unpaid volunteers often maintains the tools that power trillion-dollar products. And when those volunteers get overwhelmed, entire categories of software become fragile.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://ffmpeg.org/" rel="noopener noreferrer"&gt;FFmpeg&lt;/a&gt; situation in mid 2025 illustrated this perfectly. FFmpeg is a multimedia framework that powers Google Chrome, YouTube, Firefox, VLC, and countless other products. It’s the silent backbone of internet video, maintained by just a handful of passionate developers. When Google’s AI security tool, Big Sleep, began filing vulnerability reports to the project without providing patches, FFmpeg maintainers fired back, arguing that Google’s AI tools were dumping reports without solutions on projects largely sustained by unpaid volunteers.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1950227075576823817-661" src="https://platform.twitter.com/embed/Tweet.html?id=1950227075576823817"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1950227075576823817-661');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1950227075576823817&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;The community’s frustration was pointed and accurate: many in the FFmpeg community argue, with reason, that it is unreasonable for a trillion-dollar corporation like Google, which heavily relies on FFmpeg in its products, to shift the workload of fixing vulnerabilities to unpaid volunteers. You may not be a trillion-dollar corporation. But if you use a library every day and never contribute a bug fix, a documentation improvement, or a test case, you’re participating in the same dynamic on a smaller scale.&lt;/p&gt;

&lt;p&gt;Since the earlier shown post on X, many companies like Spotify and Elevenlabs have contributed &lt;a href="https://x.com/i/status/2014370010886459646" rel="noopener noreferrer"&gt;thousands of dollars&lt;/a&gt; to the project. You too can donate to the open-source projects you use by visiting their Sponsor page on GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. You Get Free Mentorship From Senior Engineers
&lt;/h3&gt;

&lt;p&gt;Open source is one of the few places where you can get your code reviewed by world-class engineers, for free, on real production software. That feedback loop is extraordinarily valuable, especially early in your career.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nooa6npx1j1fb46fp41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nooa6npx1j1fb46fp41.png" alt="Depiction of pull request" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you open a &lt;a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;, you’re submitting your work for scrutiny by people who have often spent years or decades on a codebase. They’ll tell you what you got wrong, how to fix it, and why the idiomatic approach matters. A review comment like “this causes an O(n²) lookup — consider a hash map here” teaches you something no tutorial video replicates, because it’s attached to code you wrote with real stakes.&lt;/p&gt;

&lt;p&gt;Here’s what a simple but well-structured first contribution might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Fork the repo on GitHub, then clone your fork locally&lt;/span&gt;
git clone https://github.com/your-username/some-project.git
&lt;span class="nb"&gt;cd &lt;/span&gt;some-project

&lt;span class="c"&gt;# 2. Create a new branch — never work directly on main&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; fix/steps-in-readme

&lt;span class="c"&gt;# 3. Make your edit, stage it, and write a clear commit message&lt;/span&gt;
git add README.md
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix: added missing steps in installation instructions"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Push your branch to your fork and open a pull request on GitHub&lt;/span&gt;
git push origin fix/steps-in-readme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This process, repeated across increasingly complex contributions, is how junior developers become mid-level ones. You’re practicing on real software, getting feedback from engineers who care about quality, and shipping real improvements. It’s structured learning with actual consequences — which is exactly what makes it stick.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. You’ll Build a Network That Opens Doors
&lt;/h3&gt;

&lt;p&gt;Open source communities are some of the most accessible professional networks in software development. You don’t need a warm introduction, a university connection, or a conference ticket. You just need to show up, be helpful, and be consistent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ATJLXdNBXxX_4KUPF" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2ATJLXdNBXxX_4KUPF" alt="Discord app" width="1024" height="683"&gt;&lt;/a&gt;&lt;br&gt;Most major open source projects maintain active Discord or Matrix communities where contributors discuss everything from bug fixes to career opportunities.
  &lt;/p&gt;

&lt;p&gt;Most active open source projects maintain a presence on platforms like &lt;a href="https://discord.com/" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; or Matrix, where contributors discuss bugs, debate design decisions, and share opportunities. These communities are global, and the people in them are often hiring, advising, or sitting on grant committees.&lt;/p&gt;

&lt;p&gt;Contributing consistently puts you in direct contact with people who can change your career trajectory. You might receive an invitation to a paid open-source fellowship.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Wxjxwx7mqaI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Programs like &lt;a href="https://www.outreachy.org/" rel="noopener noreferrer"&gt;Outreachy&lt;/a&gt; or &lt;a href="https://summerofcode.withgoogle.com/" rel="noopener noreferrer"&gt;Google Summer of Code&lt;/a&gt; pay developers to contribute to open source full-time for a summer. You might get noticed by a maintainer who later becomes a professional reference or a startup co-founder. You might simply get a perspective-shifting conversation with a developer who solves problems very differently from anyone in your immediate circle.&lt;/p&gt;

&lt;p&gt;This isn't hypothetical. Rich Harris, creator of the popular open-source JavaScript framework called Svelte, was hired by Vercel to work on it full-time. &lt;/p&gt;

&lt;p&gt;The network effect of open source is slow and compounding. The developers who’ve been contributing consistently for two or three years have not just been building a stronger portfolio but also trust. In software, that trust is the hardest thing to build from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to Start
&lt;/h3&gt;

&lt;p&gt;If you’ve never contributed before, the barrier feels higher than it actually is. You don’t need to fix a critical security vulnerability on your first pull request. Documentation improvements, test coverage additions, and bug reproductions are all legitimate, welcomed contributions. Most projects mark beginner-friendly tasks with labels like good first issue or help wanted, so you can filter to tasks that match your current skill level.&lt;/p&gt;

&lt;p&gt;The best starting point is the tools you already use every day. If you find yourself wishing a library had better error messages, check whether there’s an open issue. If the documentation confused you the first time, you already know what’s missing. Your experience as a user is valuable context that maintainers don’t always have. Over time, these small contributions compound into real-world engineering experience that is hard to replicate in isolated practice.&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>7 Web3 Security Mistakes Even Experienced Users Are Still Making</title>
      <dc:creator>Joshua Ofamba</dc:creator>
      <pubDate>Wed, 25 Mar 2026 14:43:03 +0000</pubDate>
      <link>https://dev.to/josh_the_dev/7-web3-security-mistakes-even-experienced-users-are-still-making-48a0</link>
      <guid>https://dev.to/josh_the_dev/7-web3-security-mistakes-even-experienced-users-are-still-making-48a0</guid>
      <description>&lt;p&gt;&lt;em&gt;You know not to share your seed phrase. You use a hardware wallet. You’ve read the horror stories. And yet the most costly attacks in DeFi keep hitting people who thought they’d covered the basics. Here’s what you’re probably still getting wrong.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q70sv9e3wtocg4gzeoi.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q70sv9e3wtocg4gzeoi.jpeg" alt="Glowing blocks — A blockchain!" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today’s exploits happen in the gap between what you think you’re approving and what actually executes. From compromised frontends to hidden permissions in ‘gasless’ signatures, the goal is to make a malicious transaction look like normal ones. If an attacker can gain your authorization, they don’t need your password.&lt;/p&gt;

&lt;p&gt;What follows are seven mistakes that consistently turn up in post-mortems, across wallets of every size. Some are operational habits. Some are knowledge gaps. All of them are fixable today.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. You’re Using a Single Wallet for Everything
&lt;/h2&gt;

&lt;p&gt;A single address accumulating six months of on-chain activity is a dossier. Every protocol you’ve interacted with, every approval you’ve granted, every NFT mint you’ve participated in is permanently visible. This is not inherently dangerous, but combining your main holding wallet with your active trading wallet, your test wallet, and your airdrop-farming wallet turns a manageable risk surface into an enormous one.&lt;/p&gt;

&lt;p&gt;The more consequential problem is &lt;a href="https://support.metamask.io/stay-safe/protect-yourself/wallet-and-hardware/address-poisoning-scams" rel="noopener noreferrer"&gt;&lt;strong&gt;address poisoning&lt;/strong&gt;&lt;/a&gt;. An attacker monitors your transaction history, then generates a vanity address that shares the first four and last six characters of a wallet you regularly send to. They send you a zero-value transfer from that address. You later copy-paste from your transaction history rather than your address book, and funds go to an address you’ve never controlled. This attack is low-effort, has no on-chain prevention mechanism, and works precisely because experienced users move fast and rely on visual shortcuts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Real-world impact&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Address poisoning attacks have been responsible for multi-million dollar losses in 2023 and 2024, including a well-documented case where&lt;/em&gt; &lt;a href="https://www.chainalysis.com/blog/address-poisoning-scam/#:~:text=As%20detailed%20in%20our%20Mid,of%20scam%20can%20be%20mitigated." rel="noopener noreferrer"&gt;&lt;em&gt;a trader lost $68M in WBTC&lt;/em&gt;&lt;/a&gt; &lt;em&gt;by copying a poisoned address from their own transaction history. Speed is the attacker’s ally here.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Maintain at least three distinct address buckets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cold vault&lt;/strong&gt; (hardware wallet): used strictly for long-term storage and never interacts with smart contracts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trading wallet&lt;/strong&gt; (hot wallet): handles routine DeFi activity and serves as the operational wallet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev / experimental wallet&lt;/strong&gt; : isolated environment for unaudited protocols, new deployments, or testnet spillover.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Funds should never move directly between the cold vault and the experimental wallet. Instead, route transfers through the trading wallet to introduce a deliberate, manual checkpoint.&lt;/p&gt;

&lt;p&gt;While verifying full addresses character-by-character is often impractical, you can reduce risk by using tools like &lt;a href="https://support.metamask.io/stay-safe/protect-yourself/wallet-and-hardware/address-poisoning-scams#how-can-i-protect-myself" rel="noopener noreferrer"&gt;MetaMask’s address book&lt;/a&gt; rather than copy-pasting from history.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. You’ve Never Audited Your Token Approvals
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F900%2F1%2AE2AHKHHckLgpFtlf2Bj0aw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F900%2F1%2AE2AHKHHckLgpFtlf2Bj0aw.jpeg" alt="Crypto portfolio image" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;Unlimited token approvals accumulate silently. Most wallets don’t show them proactively.
  &lt;/p&gt;

&lt;p&gt;When you approve a protocol to spend your tokens, that approval persists indefinitely unless you revoke it. Every decentralized application (dApp) interaction you’ve completed over the past two years has likely left at least one open approval. Some of those protocols have since been compromised, abandoned, or had their contracts upgraded by a multisig you have no visibility into.&lt;/p&gt;

&lt;p&gt;The attack vector is straightforward: a protocol you approved 18 months ago gets exploited. The attacker drains every wallet with an outstanding approval, not just current users. You haven’t touched that protocol in over a year, but your approval is still live. This is not a theoretical risk; it has driven the majority of DeFi drain events on record.&lt;/p&gt;

&lt;p&gt;Here’s JavaScript code using ethers.js to help you check outstanding approvals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ethers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Minimal ERC-20 ABI — allowance function only&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ERC20_ABI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function allowance(address owner, address spender) view returns (uint256)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkApproval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ownerAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spenderAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ERC20_ABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allowance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allowance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ownerAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spenderAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;constants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MaxUint256&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`⚠ Unlimited approval active for spender: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;spenderAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Allowance: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formatUnits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; tokens`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No approval outstanding.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Run a full approval audit using &lt;a href="https://revoke.cash" rel="noopener noreferrer"&gt;Revoke.cash&lt;/a&gt; across every chain you’ve been active on. Revoke anything you don’t actively use today. Going forward, prefer protocols that use exact-amount approvals over unlimited ones, and consider using a wallet interface that surfaces active approvals in-session, like Rabby.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. You’re Broadcasting Transactions Without MEV Protection
&lt;/h2&gt;

&lt;p&gt;MEV (Maximal Extractable Value) is not an abstract protocol-level concern. It hits you directly every time you execute a swap on a public mempool without protection. The most common form you’ll encounter is the &lt;strong&gt;sandwich attack&lt;/strong&gt;: a bot detects your pending transaction, front-runs it to push the price, lets your trade execute at the inflated price, then back-runs to pocket the difference. Your slippage tolerance is not a defence — it’s the parameter the bot calibrates against.&lt;/p&gt;

&lt;p&gt;On a large swap, the extracted value is often invisible to you because it sits inside your slippage allowance. On smaller trades, you simply receive fewer tokens than you should. It is a persistent, automated tax on every unprotected transaction.&lt;/p&gt;

&lt;p&gt;Here’s a sample JSON-RPC config using Flashbots Protect RPC (use on MetaMask or any EVM wallet):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;custom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;network&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;MetaMask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Settings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Networks&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"networkName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ethereum (Flashbots Protect)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rpcUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://rpc.flashbots.net"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ETH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"blockExplorer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://etherscan.io"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Transactions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;routed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;privately&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;block&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;builders,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bypassing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;mempool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;entirely.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Switch your Ethereum RPC to &lt;a href="https://protect.flashbots.net" rel="noopener noreferrer"&gt;Flashbots Protect&lt;/a&gt; for any transaction above your personal threshold for acceptable loss. Transactions sent through this endpoint are routed privately and never exposed to the public mempool. On other EVM chains, check whether an equivalent private RPC service exists; most major L2s now offer one.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. You’re Signing Permits Without Reading Them
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F900%2F0%2Ah7YN5ExFAmUcwSXx" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F900%2F0%2Ah7YN5ExFAmUcwSXx" alt="Image depicting security boundaries" width="900" height="600"&gt;&lt;/a&gt;&lt;br&gt;Hardware wallets protect your keys. They don’t protect you from signing a malicious permit.
  &lt;/p&gt;

&lt;p&gt;EIP-2612 permit signatures are gasless off-chain approvals that let a smart contract spend your tokens without a prior on-chain approval transaction. They are widely used by dApps to improve UX. They are also the primary attack vector used by modern wallet drainers, because a permit signature looks like a benign off-chain message to most wallet interfaces, and users sign them reflexively.&lt;/p&gt;

&lt;p&gt;When a malicious site asks you to “sign to verify ownership” or “connect to claim your airdrop,” what it may actually be requesting is a permit signature granting unlimited spending rights to an attacker-controlled address. Your hardware wallet won’t stop this. The keys are yours. The signature is yours. The authorisation is legitimate. The target just happens to be an attacker.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What to check before signing any off-chain message.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Look for these fields in the raw signature data your wallet surfaces:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;spender&lt;/em&gt;&lt;/strong&gt; &lt;em&gt; — is this an address you recognise?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;value&lt;/em&gt;&lt;/strong&gt; &lt;em&gt; — is this scoped to a specific amount, or is it&lt;/em&gt; &lt;strong&gt;&lt;em&gt;MaxUint256&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;deadline&lt;/em&gt;&lt;/strong&gt; &lt;em&gt; — when does this authorisation expire?&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;domain.verifyingContract&lt;/em&gt;&lt;/strong&gt; &lt;em&gt; — does this match the token contract you’re interacting with?&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Use a wallet that decodes and displays permit parameters in human-readable form before you sign. Rabby and recent versions of MetaMask have improved this significantly. Treat any off-chain signature request with the same level of scrutiny as an on-chain approval. If a site is asking you to sign something and you can’t read the fields clearly, you don’t sign it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. You Trust the Frontend, Not the Contract
&lt;/h2&gt;

&lt;p&gt;Supply chain attacks against Web3 frontends have become one of the most effective vectors in the space precisely because technically sophisticated users let their guard down on the interface layer. The assumption is that the smart contract is the attack surface, and the UI is just a convenience. This couldn’t be further from the truth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In a supply chain attack, an attacker compromises a third-party library or CDN that a dApp frontend loads at runtime.&lt;/strong&gt; The injected script intercepts your transaction parameters and silently modifies the recipient address or contract call before it reaches your wallet. The confirmation your wallet shows you looks legitimate. The transaction it signs does not go where you think it does. Notable examples include compromised versions of the &lt;a href="https://www.ledger.com/blog/a-letter-from-ledger-chairman-ceo-pascal-gauthier-regarding-ledger-connect-kit-exploit" rel="noopener noreferrer"&gt;Ledger Connect Kit in late 2023&lt;/a&gt;, which briefly affected multiple major dApp frontends simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Build the habit of verifying the contract address in any transaction your wallet surfaces before confirming, even on protocols you use regularly. Bookmark dApp URLs directly rather than navigating via search results or links in Discord. Keep your browser extensions minimal — wallet extensions with broad page permissions can be compromised too. For large transactions, consider interacting directly with a verified contract on &lt;a href="https://etherscan.io" rel="noopener noreferrer"&gt;Etherscan&lt;/a&gt; rather than through a frontend at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. You Have No Recovery Plan That Doesn’t Involve Your Seed Phrase
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A4cq-8kFTGJ0wFuJa" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2A4cq-8kFTGJ0wFuJa" alt="Seed phrase for crypto wallet" width="1024" height="684"&gt;&lt;/a&gt;&lt;br&gt;Photo by rc.xyz NFT gallery on Unsplash
  &lt;/p&gt;

&lt;p&gt;The standard advice — write your seed phrase on metal, store it in two locations, tell no one — is correct as far as it goes. The problem is that it treats recovery as a pure physical security problem. What it doesn’t address is the scenario where the seed phrase itself becomes the attack surface: coercion, inheritance, incapacitation, or the simple reality that the person most likely to access your cold storage in an emergency is also the person you’d want to have access to your funds.&lt;/p&gt;

&lt;p&gt;Social recovery, formalised in &lt;a href="https://eips.ethereum.org/EIPS/eip-4337" rel="noopener noreferrer"&gt;ERC-4337 account abstraction&lt;/a&gt;, separates custody from recovery by letting you designate a set of trusted addresses as guardians. If you lose access, a threshold of guardians can collectively authorise a recovery to a new key. No single point of failure. No seed phrase crossing a network. No trusting one person with everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;If you are managing a meaningful amount of value, migrate to or experiment with a smart contract wallet that supports social recovery — Safe (formerly Gnosis Safe) with a multisig setup is the current production-grade standard. For a more personal workflow, wallets implementing ERC-4337 like &lt;a href="https://www.ready.co/" rel="noopener noreferrer"&gt;Ready (Formerly Argent)&lt;/a&gt; offer social recovery without requiring all guardians to be co-signers. Pair this with a clearly documented but seed-phrase-free recovery procedure that a trusted person can execute without your direct involvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Your Dev Environment and Personal Wallet Share an Ecosystem
&lt;/h2&gt;

&lt;p&gt;This is the mistake most commonly made by builders who are also investors, which is a significant portion of the advanced DeFi user base. You’re testing an integration, so you clone a repo, runnpm install, and spin up a local fork. One of the dependencies in that repo has been compromised via a typosquatted package name or a maintainer account takeover. The malicious package scans your environment for private keys, seed phrases, and browser-accessible wallet storage. It finds the MetaMask profile in your browser's user data directory because you use the same machine for development and DeFi.&lt;/p&gt;

&lt;p&gt;This is not a contrived scenario. The npm ecosystem has seen a significant increase in targeted crypto-related&lt;a href="https://www.kaspersky.com/blog/npm-packages-trojanized/54280/" rel="noopener noreferrer"&gt;malicious packages&lt;/a&gt; since 2022.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Minimum viable separation&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Dedicated browser profile (or separate browser) exclusively for DeFi — no development extensions installed&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Hardware wallet for all meaningful transactions, even when it’s slower&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Development work is done in a virtual machine (VM) or on a separate physical device if the value at risk justifies it&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Never import a private key into a hot wallet on a machine used for development&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The fix
&lt;/h3&gt;

&lt;p&gt;Treat your development environment and your DeFi environment as separate security perimeters with no shared credentials. At minimum, use separate browser profiles with separate MetaMask instances and separate seed phrases. For anything beyond experimental funds, use a hardware wallet whose signing device never connects to your development machine. The friction is low. The risk reduction is substantial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;None of these mistakes requires exceptional technical sophistication to exploit. They require patience, on-chain data analysis, and the well-founded assumption that busy, technically literate users cut corners. The consistent theme across all seven is that experience creates confidence, and confidence creates exposure. The users losing the most money in DeFi today are not beginners who don’t know better — they’re people who thought they already did.&lt;/p&gt;

&lt;p&gt;Fixing all seven of these at once is a half-day of work. Pick the ones that apply to you and start there. The attacker’s cost is near zero. Your cost of prevention is not.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>blockchainsecurity</category>
      <category>smartcontractsecurit</category>
    </item>
  </channel>
</rss>
