<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>ArefXV</title>
        <link>https://paragraph.com/@arefxv</link>
        <description>Smart contract dev 

Solidity &amp; Vyper

Security researcher</description>
        <lastBuildDate>Sun, 30 Aug 2026 17:45:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>ArefXV</title>
            <url>https://storage.googleapis.com/papyrus_images/3591233afcebcd6f4d0ef30056e0c23e9d9fd6e070dfd1f377d98fbee693626d.png</url>
            <link>https://paragraph.com/@arefxv</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[How ETH Is Received in Smart Contracts]]></title>
            <link>https://paragraph.com/@arefxv/how-eth-is-received-in-smart-contracts</link>
            <guid>AVrDlSlNbHa4e5VITapW</guid>
            <pubDate>Sat, 14 Jun 2025 16:44:36 GMT</pubDate>
            <description><![CDATA[How ETH Is Received in Smart Contracts — receive(), fallback(), and Common MistakesSmart contracts on Ethereum can receive ETH directly. But what actually happens when someone sends ETH to a contract? And why do some transactions fail silently while others go through? Let’s dive deep into how Ether is handled in Solidity, the differences between receive() and fallback(), and some key developer mistakes you should avoid.ETH Transfers 101When you send ETH to a contract, one of two functions wil...]]></description>
            <content:encoded><![CDATA[<h1 id="h-how-eth-is-received-in-smart-contracts-receive-fallback-and-common-mistakes" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">How ETH Is Received in Smart Contracts — <code>receive()</code>, <code>fallback()</code>, and Common Mistakes</h1><p>Smart contracts on Ethereum can receive ETH directly. But what actually happens when someone sends ETH to a contract? And why do some transactions fail silently while others go through?</p><p>Let’s dive deep into how Ether is handled in Solidity, the differences between <code>receive()</code> and <code>fallback()</code>, and some key developer mistakes you should avoid.</p><hr><h2 id="h-eth-transfers-101" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">ETH Transfers 101</h2><p>When you send ETH to a contract, one of two functions will be triggered based on the context:</p><ul><li><p><code>receive() external payable</code></p></li><li><p><code>fallback() external payable</code></p></li></ul><p>These are <strong>special functions</strong> in Solidity that aren’t called directly in code. They get triggered under very specific circumstances.</p><hr><h2 id="h-when-does-receive-run" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">When Does <code>receive()</code> Run?</h2><p>The <code>receive()</code> function runs when:</p><ol><li><p>A contract receives <strong>ETH with empty calldata</strong></p></li><li><p>The <code>receive()</code> function is marked <strong>payable</strong></p></li></ol><p>Example:</p><pre data-type="codeBlock" text="receive() external payable {
    emit Received(msg.sender, msg.value);
}
"><code><span class="hljs-function"><span class="hljs-keyword">receive</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
    <span class="hljs-keyword">emit</span> Received(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>);
}
</code></pre><p>If someone calls the contract with just ETH (e.g., using <code>.transfer()</code> or sending ETH directly via MetaMask), this function will run.</p><p><strong>Use case:</strong> Simple ETH deposits with no logic or function calls.</p><hr><h2 id="h-when-does-fallback-run" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">When Does <code>fallback()</code> Run?</h2><p>The <code>fallback()</code> function is more general. It runs when:</p><ol><li><p>A function is called that <strong>doesn’t exist</strong></p></li><li><p>OR when calldata is not empty</p></li><li><p>AND <code>receive()</code> is either not present or doesn’t match</p></li></ol><pre data-type="codeBlock" text="fallback() external payable { emit FallbackCalled(msg.sender, msg.value, msg.data); }
"><code><span class="hljs-function"><span class="hljs-keyword">fallback</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{ <span class="hljs-keyword">emit</span> FallbackCalled(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">data</span>); }
</code></pre><p>You can also define a <strong>non-payable</strong> fallback if you want to reject ETH:</p><pre data-type="codeBlock" text="fallback() external { revert(&quot;ETH not accepted&quot;); }
"><code><span class="hljs-function"><span class="hljs-keyword">fallback</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> </span>{ <span class="hljs-keyword">revert</span>(<span class="hljs-string">"ETH not accepted"</span>); }
</code></pre><hr><h2 id="h-common-developer-mistakes" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Common Developer Mistakes</h2><ol><li><p>Not defining receive() or fallback() If your contract is meant to accept ETH but has neither, any direct ETH transfer will revert.</p></li></ol><p>✅ Fix: Add at least one payable function (receive() or fallback()).</p><ol><li><p>Heavy Logic in Fallbacks Since fallback functions can get triggered unintentionally, avoid writing logic-heavy operations that might increase gas use or create vulnerabilities.</p></li><li><p>Not Handling msg.data Sometimes, users (or attackers) send ETH with extra calldata. If you&apos;re only using receive(), those transactions will revert. Always consider a fallback for maximum safety.</p></li></ol><p><strong>Real-World Example: Accepting ETH in a Treasury Contract solidity Copy Edit</strong></p><pre data-type="codeBlock" text="// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract Treasury {
    address public owner;

    event Received(address sender, uint256 amount);
    event FallbackCalled(address sender, uint256 amount, bytes data);

    constructor() {
        owner = msg.sender;
    }

    receive() external payable {
        emit Received(msg.sender, msg.value);
    }

    fallback() external payable {
        emit FallbackCalled(msg.sender, msg.value, msg.data);
    }

    function withdraw() external {
        require(msg.sender == owner, &quot;Only owner&quot;);
        payable(owner).transfer(address(this).balance);
    }
}
"><code><span class="hljs-comment">// SPDX-License-Identifier: MIT</span>
<span class="hljs-meta"><span class="hljs-keyword">pragma</span> <span class="hljs-keyword">solidity</span> ^0.8.25;</span>

<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Treasury</span> </span>{
    <span class="hljs-keyword">address</span> <span class="hljs-keyword">public</span> owner;

    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">Received</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> sender, <span class="hljs-keyword">uint256</span> amount</span>)</span>;
    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">FallbackCalled</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> sender, <span class="hljs-keyword">uint256</span> amount, <span class="hljs-keyword">bytes</span> data</span>)</span>;

    <span class="hljs-function"><span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) </span>{
        owner <span class="hljs-operator">=</span> <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">receive</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
        <span class="hljs-keyword">emit</span> Received(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">fallback</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title"><span class="hljs-keyword">payable</span></span> </span>{
        <span class="hljs-keyword">emit</span> FallbackCalled(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">value</span>, <span class="hljs-built_in">msg</span>.<span class="hljs-built_in">data</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params"></span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> </span>{
        <span class="hljs-built_in">require</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span> owner, <span class="hljs-string">"Only owner"</span>);
        <span class="hljs-keyword">payable</span>(owner).<span class="hljs-built_in">transfer</span>(<span class="hljs-keyword">address</span>(<span class="hljs-built_in">this</span>).<span class="hljs-built_in">balance</span>);
    }
}
</code></pre><p>Try sending ETH from your wallet or via Remix — both receive and fallback will log different events based on how the ETH was sent.</p><hr><h2 id="h-what-about-vyper" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What About Vyper?</h2><p>Vyper handles this similarly but doesn’t use <code>receive()</code> or <code>fallback()</code> keywords directly. It uses:</p><pre data-type="codeBlock" text="@external @payable def __default__(): # Code here runs on unknown function call or direct ETH
"><code><span class="hljs-variable">@external</span> <span class="hljs-variable">@payable</span> def <span class="hljs-built_in">__default__</span>(): # Code here runs on unknown function call or direct ETH
</code></pre><p>Everything is handled in <code>__default__</code>, so you must manually manage what to accept and reject.</p><h2 id="h-best-practices" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Best Practices</h2><ul><li><p>Always define <code>receive()</code> if your contract is meant to <strong>receive ETH directly</strong>.</p></li><li><p>Use a <code>fallback()</code> to <strong>catch unexpected calls</strong> or ETH sent with data.</p></li><li><p>Don’t rely on these functions for <strong>business logic</strong>.</p></li><li><p>Always emit logs for transparency (<code>emit Received(...)</code>) for off-chain monitoring.</p></li></ul><hr><h2 id="h-final-words" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Final Words</h2><p>Many developers forget to test how their contracts behave with unexpected inputs or ETH sent manually. A missing <code>receive()</code> function can easily break dApps like fundraising contracts, treasuries, or NFT mints.</p><p>When building production-grade contracts, <strong>always include proper ETH handling</strong>, and test them via <code>.call</code>, <code>.transfer</code>, or even raw transactions.</p><hr><blockquote><p>Want me to cover gas optimizations, reentrancy, or cross-chain bridging next? Stay tuned.</p></blockquote>]]></content:encoded>
            <author>arefxv@newsletter.paragraph.com (ArefXV)</author>
        </item>
    </channel>
</rss>