<?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: Astrophel</title>
    <description>The latest articles on DEV Community by Astrophel (@astrophelverse).</description>
    <link>https://dev.to/astrophelverse</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%2F3672715%2F0323419d-9789-44bc-9bd6-b796e3aceaa9.png</url>
      <title>DEV Community: Astrophel</title>
      <link>https://dev.to/astrophelverse</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/astrophelverse"/>
    <language>en</language>
    <item>
      <title>I'm Killing Laziness While Building Limbo and Here Is How You Can Too</title>
      <dc:creator>Astrophel</dc:creator>
      <pubDate>Sat, 16 May 2026 19:32:54 +0000</pubDate>
      <link>https://dev.to/astrophelverse/im-killing-laziness-while-building-limbo-and-here-is-how-you-can-too-56e5</link>
      <guid>https://dev.to/astrophelverse/im-killing-laziness-while-building-limbo-and-here-is-how-you-can-too-56e5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Some days I open my codebase and I genuinely ask myself what I am even building.&lt;/strong&gt;&lt;br&gt;
Not in a motivational crisis kind of way. More like a quiet, dangerous kind of doubt. The kind that doesn't scream at you, it just sits there. Whispering. Is this even worth it?&lt;br&gt;
I am building Limbo. A smart contract security auditing platform. Four tools running simultaneously across your entire codebase, every finding verified by Foundry before it touches a report. I believe in it completely. And some days it still feels like I am building something nobody asked for in a room by myself.&lt;br&gt;
That feeling is normal. What you do with it is everything.&lt;/p&gt;

&lt;p&gt;Here is what I figured out.&lt;br&gt;
Developers are really good at one thing nobody talks about, getting bored of their own ideas. You start something, the first week is electric, the second week is okay, the third week you are already thinking about the next thing. The idea that felt like your life's purpose is now just another folder on your desktop.&lt;br&gt;
The problem is not laziness. The problem is that you are letting your feelings run the project.&lt;br&gt;
The day the idea thrills you, you work. The day it does not, you vibe. And slowly, without realizing it, you have built a system where your progress depends entirely on your mood. That is not a project. That is a hobby with ambitions.&lt;/p&gt;

&lt;p&gt;The fix I found is embarrassingly simple. Daily limits.&lt;br&gt;
Pick your number. Mine is 5 hours. Every single day, 5 hours goes into Limbo. Not because I feel like it. Not because the idea is exciting today. Because that is the rule.&lt;br&gt;
The day you are locked in and everything is clicking, follow the rule.&lt;br&gt;
The day you are questioning everything and nothing makes sense, follow the rule.&lt;br&gt;
The rule does not care how you feel. That is the whole point.&lt;br&gt;
And what happens when you just follow the rule every day is something nobody tells you about. Progress starts to feel like evidence. You look back two weeks and Slither is working. You look back a month and Mythril is working. The doubt does not disappear but it gets quieter because now you have receipts.&lt;/p&gt;

&lt;p&gt;I also have an ego that refuses to let me quit something I love.&lt;br&gt;
That sounds like a flex but it is actually just stubbornness with direction. Limbo is not something I started because it seemed profitable or because someone told me to. I started it because I felt the problem personally. I was a security researcher putting my name on AI-generated audit reports and getting beaten to findings every single time. That pain is real. That pain keeps me going on the days the code makes no sense and the tools are disrespecting me.&lt;br&gt;
If your idea does not have that kind of root to it, the daily limit alone will not save you. You need a reason that does not expire when the excitement does.&lt;/p&gt;

&lt;p&gt;So here is the actual system:&lt;br&gt;
Find the thing you genuinely love building. Not the thing that looks good on Twitter. Not the thing you think will make money. The thing you would still be building if nobody was watching.&lt;br&gt;
Set your daily hours and treat them like a meeting you cannot cancel.&lt;br&gt;
Track your progress every single day. Not to feel good about yourself. To have evidence when the doubt comes back.&lt;br&gt;
And when the doubt does come back, because it will, do not fight it. Just open the codebase and follow the rule.&lt;br&gt;
Limbo is still not finished. Echidna and Halmos are still giving me problems. But I have not missed a day. And that matters more than any single breakthrough.&lt;br&gt;
Lock in. Follow the rule. Love what you are building.&lt;br&gt;
The rest will come.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>security</category>
    </item>
    <item>
      <title>I Built a Smart Contract Auditing Tool Because AI Was Embarrassing Me</title>
      <dc:creator>Astrophel</dc:creator>
      <pubDate>Fri, 15 May 2026 11:07:32 +0000</pubDate>
      <link>https://dev.to/astrophelverse/i-built-a-smart-contract-auditing-tool-because-ai-was-embarrassing-me-3bk9</link>
      <guid>https://dev.to/astrophelverse/i-built-a-smart-contract-auditing-tool-because-ai-was-embarrassing-me-3bk9</guid>
      <description>&lt;p&gt;&lt;strong&gt;I used to be a smart contract security researcher.&lt;/strong&gt;&lt;br&gt;
Key word: &lt;em&gt;used to&lt;/em&gt;.&lt;br&gt;
Not because I quit, because I got honest with myself about what I was actually doing. I was using AI to write my audit reports. Finding vulnerabilities, sure, but letting AI carry the write-up. Felt efficient. Felt smart even.&lt;br&gt;
Then reality started hitting different.&lt;br&gt;
&lt;strong&gt;Duplicates&lt;/strong&gt;. Over and over. Someone else submitted the same finding faster. Or worse: AI flagged the two most obvious things in the contract and called it a day. It wasn’t auditing. It was skimming. AI was skimming my clients' contracts and I was putting my name on it.&lt;br&gt;
That bothered me more than I expected.&lt;br&gt;
So I asked a different question. Not "how do I audit faster", but what if the whole process was built differently from scratch? Cheap, real, impossible to fake. Something a security researcher could trust and a developer could actually afford.&lt;br&gt;
That’s where Limbo started. It’s not finished. But the story of building it is already worth telling.&lt;br&gt;
The idea was simple and insane at the same time. Four tools; Slither, Mythril, Echidna, Halmos , each attacking a contract differently. Every finding verified by Foundry before AI touches it. AI doesn’t find bugs in Limbo. It confirms them. There’s a difference and that difference is everything.&lt;br&gt;
I wanted it to feel like Certora, lol, rigorous, real, no vibes.&lt;br&gt;
Then came the fun part. I needed a developer.&lt;br&gt;
You know that moment when you price something out and it’s $500–1k minimum and you have exactly zero of that? Yeah. So I made the only logical decision: build it myself. With AI.&lt;br&gt;
I know how that sounds.&lt;br&gt;
Here’s what nobody tells you about building with AI. It’s not a vending machine. You can’t just explain what you want and watch it appear. You explain something, it writes code, and half the time it goes a completely different direction than what you had in your head. You tell it to fix it. It doesn’t fully understand what you’re even saying. You try again. It confidently produces something that looks right and is completely wrong.&lt;br&gt;
It’s like handing someone your vision and getting back a drawing of something that rhymes with your vision.&lt;br&gt;
I bought a Claude subscription. Thought that was the move. And Claude is genuinely the only one that actually gets context, but man, even Claude made so many mistakes it wasn’t funny. What I had after the first stretch wasn’t Limbo. It was a skeleton wearing Limbo’s clothes.&lt;br&gt;
Slither wasn’t working. Mythril wasn’t working. Echidna and Halmos? They looked at my prompts and said this is why we aren’t AI. 💀&lt;br&gt;
Two weeks of debugging the entire codebase. Not building. Not adding features. Just two weeks of going line by line trying to understand a workspace I’d never been in before, Rust, Solidity toolchains, Docker configs, dependency hell. I should have hired a developer. Two weeks to get Slither and Mythril functional. Echidna and Halmos are still fighting me. &lt;br&gt;
And I’m still going.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the technical people, here’s exactly what Limbo does:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Limbo runs Slither, Mythril, Echidna, and Halmos across your entire codebase at the same time. Not one after the other. All four, simultaneously, hitting your contracts from every angle, static analysis, symbolic execution, fuzzing, formal verification. When they find something, that finding doesn’t go anywhere near a report yet.&lt;br&gt;
AI steps in for exactly one job: write a PoC. One file. Then it runs that PoC through Foundry and keeps forging it until Foundry confirms the bug is real. If it can’t be confirmed, it doesn’t exist as far as Limbo is concerned. And if any of the four tools fail or start acting up mid-scan? AI’s only other job is to point them back on track.&lt;br&gt;
That’s it. AI is infrastructure. The tools are the auditors.&lt;br&gt;
No finding in your report was put there by a language model guessing. Every single one was found by a tool, proven by Foundry, and documented for you to fix.&lt;br&gt;
Because here’s what building this taught me that I couldn’t have learned any other way, AI is good at one thing in security. Verifying. Not finding. The moment you ask AI to find your bugs you’ve already lost. It catches the obvious ones, writes it up clean, and leaves the real stuff buried. For someone else to find. Or for an exploit to find.&lt;br&gt;
That’s what I was doing before. That’s why I’m building something different.&lt;br&gt;
I joined Cyfrin Updraft to actually learn; Solidity, Rust, the fundamentals I was missing. Yes I was already a security researcher. No that wasn’t enough. Humbling is an understatement.&lt;br&gt;
But if you’re getting into smart contract auditing right now; Cantina, HackerOne, Code4rena (RIP, if you haven’t heard, they’re down), anywhere hear me:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not use AI to find bugs. Learn to find bugs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I made that mistake. I’m still paying for it in ways that turned into this entire project. The knowledge you build when you actually learn this is worth more than any shortcut. Shoutout Cyfrin Updraft, no sponsorship, just facts.&lt;br&gt;
Limbo isn’t finished. Echidna and Halmos are still out here disrespecting me. But it’s real, it’s being built in public, and when it’s done, nothing in it will be fake.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>web3</category>
      <category>smartcontract</category>
      <category>programming</category>
    </item>
    <item>
      <title>Optimizing Integer-Constrained Circle Packing using Differential Evolution in Python.</title>
      <dc:creator>Astrophel</dc:creator>
      <pubDate>Sun, 21 Dec 2025 16:24:50 +0000</pubDate>
      <link>https://dev.to/astrophelverse/optimizing-integer-constrained-circle-packing-using-differential-evolution-in-python-1ad9</link>
      <guid>https://dev.to/astrophelverse/optimizing-integer-constrained-circle-packing-using-differential-evolution-in-python-1ad9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction: The "Brute Force" Trap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’ll be honest: I thought this would be easy. My goal was simple: fit as many non-overlapping circles as possible into a 100x100 pixel grid.&lt;/p&gt;

&lt;p&gt;My first instinct was to use a standard Brute Force approach. I wrote a script to randomly guess x, y coordinates and radii. I let it run for hours. The result? A mess. The circles either overlapped constantly or left huge, inefficient gaps. The problem wasn't the geometry; it was the grid.&lt;/p&gt;

&lt;p&gt;Unlike pure math, where a circle can be at position 10.5553, my system was constrained to an Integer Grid (pixels). This seemingly small constraint broke standard geometric formulas. The "perfect" mathematical position was often "illegal" in my pixel grid.&lt;/p&gt;

&lt;p&gt;I realized I didn't need a calculator; I needed an evolution. I needed an algorithm that could "learn" the landscape of the grid. That’s why I turned to Differential Evolution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Logic (Defining the Chaos)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a perfect world, I could use Descartes' Circle Theorem to calculate exactly where every circle should go. That gives you those beautiful, symmetric patterns (often called Apollonian Gaskets).&lt;/p&gt;

&lt;p&gt;But my problem wasn't theoretical. It was practical.&lt;br&gt;
I didn't want a pretty shape; I wanted density. I wanted to know: "If I throw 10 circles into this box, what is the absolute best way to arrange them so they don't overlap, but also waste zero space?"&lt;/p&gt;

&lt;p&gt;This is where standard formulas fail. Formulas break when you force them onto an Integer Grid (pixels). A formula might say the circle belongs at x=50.4, but my pixel grid only allows x=50 or x=51. That rounding error causes overlaps.&lt;/p&gt;

&lt;p&gt;So, I had to treat this as an Optimization Problem, not a Geometry problem.&lt;/p&gt;

&lt;p&gt;The "Chromosome" Strategy&lt;/p&gt;

&lt;p&gt;I set up the problem for the Differential Evolution algorithm by defining a "Chromosome", a single list of numbers that represents the entire solution.&lt;/p&gt;

&lt;p&gt;Instead of solving for one circle at a time, I told the solver:&lt;br&gt;
"Here is a list of 30 numbers representing 10 circles (x, y, radius for each). Shuffle these numbers until you minimize the 'Pain'."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Pain" (Objective) Function&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the secret sauce. The algorithm needs to know when it's doing a bad job. I defined "Pain" (Cost) using two simple rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Overlap Penalty: If the distance between two circles is less than the sum of their radii, that's a collision. I added a massive penalty (10,000 points) for every pixel of overlap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Wall Penalty: If a circle crosses the grid boundary (x &amp;lt; 0 or x &amp;gt; 100), that's illegal. Another massive penalty.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Reward: If the circles are safe, I subtracted the Total Radius from the score. This forces the algorithm to "inflate" the circles as much as possible to fill the empty voids.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Implementation: From Theory to Python&lt;/strong&gt;&lt;br&gt;
Here is the exact script I used. I utilized scipy.optimize.differential_evolution because it handles the "stochastic" (random) nature of this problem much better than standard gradient descent.&lt;/p&gt;

&lt;p&gt;Notice the objective function. This is where the magic happens. It’s not just math; it’s a set of strict rules telling the algorithm exactly what "failure" looks like.&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import numpy as np
from scipy.optimize import differential_evolution
import matplotlib.pyplot as plt
import matplotlib.patches as patches
# 1. CONFIGURATION
# We define the constraints of our "Integer Grid"
GRID_SIZE = 100 
N_CIRCLES = 10   
def objective(x):
    """
    The Cost Function. 
    The goal is to MINIMIZE this score.
    High Score = Bad (Overlaps). Low Score = Good (Packed).
    """
    # Reshape the flat list back into (x, y, r) for each circle
    circles = x.reshape((N_CIRCLES, 3))
    penalty = 0   
    for i in range(N_CIRCLES):
        xi, yi, ri = circles[i]     
        # Rule 1: Don't leave the grid!
        # If a circle crosses the 0 or 100 line, punish it heavily.
        if xi - ri &amp;lt; 0 or xi + ri &amp;gt; GRID_SIZE: penalty += 1000
        if yi - ri &amp;lt; 0 or yi + ri &amp;gt; GRID_SIZE: penalty += 1000     
        # Rule 2: Don't touch your neighbors!
        for j in range(i + 1, N_CIRCLES):
            xj, yj, rj = circles[j]
            # Calculate distance between centers
            dist = np.sqrt((xi - xj)**2 + (yi - yj)**2)           
            # If distance &amp;lt; sum of radii, they are overlapping
            if dist &amp;lt; (ri + rj): 
                # The penalty scales with how bad the overlap is
                penalty += 10000 * (ri + rj - dist)              
    # Rule 3: Be Big!
    # We subtract the total radius because 'differential_evolution' 
    # tries to minimize the number. Subtracting makes it want larger circles.
    total_radius = np.sum(circles[:, 2])
    return penalty - total_radius 
# 2. THE EVOLUTION
# We set bounds for x (0-100), y (0-100), and radius (1-25)
bounds = [(0, GRID_SIZE), (0, GRID_SIZE), (1, GRID_SIZE/4)] * N_CIRCLES
# This line runs the genetic algorithm. It breeds generation after generation.
result = differential_evolution(objective, bounds, maxiter=100, workers=-1)
# 3. VISUALIZATION
# Plot the winner to see if it actually worked
fig, ax = plt.subplots(figsize=(6, 6))
best_circles = result.x.reshape((N_CIRCLES, 3))
for c in best_circles:
    circle = patches.Circle((c[0], c[1]), c[2], edgecolor='blue', facecolor='cyan', alpha=0.5)
    ax.add_patch(circle)
ax.set_xlim(0, GRID_SIZE)
ax.set_ylim(0, GRID_SIZE)
ax.set_aspect('equal')
plt.title(f"Optimized Packing on {GRID_SIZE}x{GRID_SIZE} Grid")
plt.show()
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Result&lt;/p&gt;

&lt;p&gt;After running the evolution for just a few seconds (approx 100 generations), the algorithm converged.&lt;/p&gt;

&lt;p&gt;Unlike Brute Force, which blindly guesses, you can watch Differential Evolution "learn." In the first generation, circles are overlapping everywhere. By generation 50, they have learned to separate. By generation 100, they expand to fill the available voids.&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%2Fjhw5pu903yzri64094vq.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%2Fjhw5pu903yzri64094vq.png" alt=" " width="531" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion: Chaos is Efficient&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I started this experiment, I wanted a perfect, symmetric packing. I failed. But in failing, I found something more useful.&lt;/p&gt;

&lt;p&gt;By treating the "Circle Packing Problem" as an evolutionary optimization task rather than a geometry task, I was able to solve it on a constrained Integer Grid, something standard formulas struggle with.&lt;/p&gt;

&lt;p&gt;The final result isn't a perfect fractal. It’s chaotic. It’s messy. But it is dense. The algorithm found a way to utilize 78% of the available grid space in under 30 seconds of compute time.&lt;/p&gt;

&lt;p&gt;For developers working on sprite sheets, texture atlases, or even physical storage systems, this is the lesson: Sometimes, you don't need the perfect formula. You just need a good definition of "Pain," and enough generations to evolve a solution that works.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>maths</category>
      <category>python</category>
      <category>equation</category>
    </item>
  </channel>
</rss>
