{"id":22231,"date":"2026-08-02T04:24:08","date_gmt":"2026-08-02T04:24:08","guid":{"rendered":"https:\/\/cryptoted.net\/index.php\/2026\/08\/02\/smart-contract-security-ethereum-foundation-blog\/"},"modified":"2026-08-02T04:24:08","modified_gmt":"2026-08-02T04:24:08","slug":"smart-contract-security-ethereum-foundation-blog","status":"publish","type":"post","link":"https:\/\/cryptoted.net\/index.php\/2026\/08\/02\/smart-contract-security-ethereum-foundation-blog\/","title":{"rendered":"Smart Contract Security | Ethereum Foundation Blog"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div id=\"\">\n<p class=\"chakra-text css-gi02ar\">Solidity was started in October 2014 when neither the Ethereum network nor the virtual machine had any real-world testing, the gas costs at that time were even drastically different from what they are now. Furthermore, some of the early design decisions were taken over from Serpent. During the last couple of months, examples and patterns that were initially considered best-practice were exposed to reality and some of them actually turned out to be anti-patterns. Due to that, we recently updated some of the <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"https:\/\/solidity.readthedocs.org\">Solidity documentation<\/a>, but as most people probably do not follow the stream of github commits to that repository, I would like to highlight some of the findings here.<\/p>\n<p class=\"chakra-text css-gi02ar\">I will not talk about the minor issues here, please read up on them in the <a target=\"_blank\" rel=\"noopener\" class=\"chakra-link css-vezwxf\" href=\"http:\/\/solidity.readthedocs.io\/en\/latest\/miscellaneous.html#pitfalls\">documentation<\/a>.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"sending-ether\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"sending ether permalink\" href=\"#sending-ether\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a><strong>Sending Ether<\/strong><\/h2>\n<p>Sending Ether is supposed to be one of the simplest things in Solidity, but it turns out to have some subtleties most people do not realise.<\/p>\n<p class=\"chakra-text css-gi02ar\">It is important that at best, the recipient of the ether initiates the payout. The following is a <strong>BAD<\/strong> example of an auction contract:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>\/\/ THIS IS A NEGATIVE EXAMPLE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span> DO NOT USE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>\n<\/span><span>contract auction <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>  address highestBidder<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  uint highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">bid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>msg.value <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\"><span> highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> throw<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span>\n<\/span><span>      highestBidder.send<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span> \/\/ refund previous bidder\n<\/span><span>    highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    highestBid <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> msg.value<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span\/><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">Because of the maximal stack depth of 1024 the new bidder can always increase the stack size to 1023 and then call <span class=\"chakra-text css-ons8vw\">bid()<\/span> which will cause the <span class=\"chakra-text css-ons8vw\">send(highestBid)<\/span> call to silently fail (i.e. the previous bidder will not receive the refund), but the new bidder will still be highest bidder. One way to check whether <span class=\"chakra-text css-ons8vw\">send<\/span> was successful is to check its return value:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>\/\/\/ THIS IS STILL A NEGATIVE EXAMPLE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span> DO NOT USE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>\n<\/span><span\/><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>highestBidder.send<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">))<\/span><span>\n<\/span><span>    throw<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><\/code><\/pre>\n<p>The <\/p>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>throw<\/span><\/code><\/pre>\n<p> statement causes the current call to be reverted. This is a bad idea, because the recipient, e.g. by implementing the fallback function as <\/p>\n<pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">function<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span> throw<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><\/code><\/pre>\n<p> can always force the Ether transfer to fail and this would have the effect that nobody can overbid her.<\/p><\/div>\n<p class=\"chakra-text css-gi02ar\">The only way to prevent both situations is to convert the sending pattern into a withdrawing pattern by giving the recipient control over the transfer:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>\/\/\/ THIS IS STILL A NEGATIVE EXAMPLE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span> DO NOT USE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>\n<\/span><span>contract auction <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>  address highestBidder<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  uint highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  mapping<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>address <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">&gt;<\/span><span> uint<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">bid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>msg.value <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\"><span> highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> throw<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span>\n<\/span><span>      refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>highestBidder<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">+=<\/span><span> highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    highestBid <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> msg.value<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">withdrawRefund<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>msg.sender.send<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">))<\/span><span>\n<\/span><span>      refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span\/><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span> <\/span><\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">Why does it still say &#8220;negative example&#8221; above the contract? Because of gas mechanics, the contract is actually fine, but it is still not a good example. The reason is that it is impossible to prevent code execution at the recipient as part of a send. This means that while the send function is still in progress, the recipient can call back into withdrawRefund. At that point, the refund amount is still the same and thus they would get the amount again and so on. In this specific example, it does not work, because the recipient only gets the gas stipend (2100 gas) and it is impossible to perform another send with this amount of gas. The following code, though, is vulnerable to this attack: <span class=\"chakra-text css-ons8vw\">msg.sender.call.value(refunds[msg.sender])()<\/span>.<\/p>\n<p class=\"chakra-text css-gi02ar\">Having considered all this, the following code should be fine (of course it is still not a complete example of an auction contract):<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>contract auction <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>  address highestBidder<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  uint highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  mapping<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>address <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">&gt;<\/span><span> uint<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">bid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>msg.value <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\"><span> highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> throw<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span>\n<\/span><span>      refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>highestBidder<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">+=<\/span><span> highestBid<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    highestBidder <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    highestBid <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> msg.value<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">withdrawRefund<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>    uint refund <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>msg.sender.send<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>refund<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">))<\/span><span>\n<\/span><span>     refunds<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> refund<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span\/><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p class=\"chakra-text css-gi02ar\">Note that we did not use throw on a failed send because we are able to revert all state changes manually and not using throw has a lot less side-effects.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"using-throw\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"using throw permalink\" href=\"#using-throw\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a><strong>Using Throw<\/strong><\/h2>\n<p>The throw statement is often quite convenient to revert any changes made to the state as part of the call (or whole transaction depending on how the function is called). You have to be aware, though, that it also causes all gas to be spent and is thus expensive and will potentially stall calls into the current function. Because of that, I would like to recommend to use it <strong>only<\/strong> in the following situations:<\/p>\n<p class=\"chakra-text css-gi02ar\"><strong>1. Revert Ether transfer to the current function<\/strong><\/p>\n<p class=\"chakra-text css-gi02ar\">If a function is not meant to receive Ether or not in the current state or with the current arguments, you should use throw to reject the Ether. Using throw is the only way to reliably send back Ether because of gas and stack depth issues: The recipient might have an error in the fallback function that takes too much gas and thus cannot receive the Ether or the function might have been called in a malicious context with too high stack depth (perhaps even preceding the calling function).<\/p>\n<p class=\"chakra-text css-gi02ar\">Note that accidentally sending Ether to a contract is not always a UX failure: You can never predict in which order or at which time transactions are added to a block. If the contract is written to only accept the first transaction, the Ether included in the other transactions has to be rejected.<\/p>\n<p class=\"chakra-text css-gi02ar\"><strong>2. Revert effects of called functions<\/strong><\/p>\n<p class=\"chakra-text css-gi02ar\">If you call functions on other contracts, you can never know how they are implemented. This means that the effects of these calls are also not know and thus the only way to revert these effects is to use throw. Of course you should always write your contract to not call these functions in the first place, if you know you will have to revert the effects, but there are some use-cases where you only know that after the fact.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"loops-and-the-block-gas-limit\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"loops and the block gas limit permalink\" href=\"#loops-and-the-block-gas-limit\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a><strong>Loops and the Block Gas Limit<\/strong><\/h2>\n<p>There is a limit of how much gas can be spent in a single block. This limit is flexible, but it is quite hard to increase it. This means that every single function in your contract should stay below a certain amount of gas in all (reasonable) situations. The following is a BAD example of a voting contract:<\/p>\n<div class=\"chakra-stack css-1jx0in4\">\n<pre><pre style=\"color:white;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding:1em;margin:0.5em 0;overflow:auto;background:#011627\"><code class=\"language-bash\" style=\"color:#d6deeb;font-family:Consolas, Monaco, &quot;Andale Mono&quot;, &quot;Ubuntu Mono&quot;, monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;font-size:1em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none\"><span>\/\/\/ THIS IS STILL A NEGATIVE EXAMPLE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span> DO NOT USE<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">!<\/span><span>\n<\/span><span>contract Voting <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>  mapping<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>address <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">&gt;<\/span><span> uint<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> voteWeight<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  address<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span> yesVotes<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  uint requiredWeight<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  address beneficiary<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  uint amount<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">voteYes<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span> yesVotes.push<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>msg.sender<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">function<\/span><span> <\/span><span class=\"token function-name\" style=\"color:rgb(130, 170, 255)\">tallyVotes<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">{<\/span><span>\n<\/span><span>    uint yesVotes<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">for<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>uint i <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">=<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(247, 140, 108)\">0<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span> i <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\"><span> yesVotes.length<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span> ++i<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span>\n<\/span><span>      yesVotes <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">+=<\/span><span> voteWeight<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>yesVotes<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">[<\/span><span>i<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">]<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>    <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">if<\/span><span> <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>yesVotes <\/span><span class=\"token\" style=\"color:rgb(127, 219, 202)\">&gt;<\/span><span> requiredWeight<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span>\n<\/span><span>      beneficiary.send<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">(<\/span><span>amount<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">)<\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">;<\/span><span>\n<\/span><span>  <\/span><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><span>\n<\/span><span\/><span class=\"token\" style=\"color:rgb(199, 146, 234)\">}<\/span><\/span><\/code><\/pre>\n<\/div>\n<p>The contract actually has several issues, but the one I would like to highlight here is the problem of the loop: Assume that vote weights are transferrable and splittable like tokens (think of the DAO tokens as an example). This means that you can create an arbitrary number of clones of yourself. Creating such clones will increase the length of the loop in the tallyVotes function until it takes more gas than is available inside a single block.<\/p>\n<p class=\"chakra-text css-gi02ar\">This applies to anything that uses loops, also where loops are not explicitly visible in the contract, for example when you copy arrays or strings inside storage. Again, it is fine to have arbitrary-length loops if the length of the loop is controlled by the caller, for example if you iterate over an array that was passed as a function argument. But <strong>never<\/strong> create a situation where the loop length is controlled by a party that would not be the only one suffering from its failure.<\/p>\n<p class=\"chakra-text css-gi02ar\">As a side note, this was one reason why we now have the concept of blocked accounts inside the DAO contract: Vote weight is counted at the point where the vote is cast, to prevent the fact that the loop gets stuck, and if the vote weight would not be fixed until the end of the voting period, you could cast a second vote by just transferring your tokens and then voting again.<\/p>\n<h2 class=\"chakra-heading group css-1kpzc4q\" id=\"receiving-ether--the-fallback-function\" data-group=\"true\"><a class=\"chakra-link css-128fqrf\" aria-label=\"receiving ether  the fallback function permalink\" href=\"#receiving-ether--the-fallback-function\"><svg viewbox=\"0 0 24 24\" focusable=\"false\" class=\"chakra-icon css-173jpr1\"><g fill=\"currentColor\"><path d=\"M10.458,18.374,7.721,21.11a2.853,2.853,0,0,1-3.942,0l-.892-.891a2.787,2.787,0,0,1,0-3.941l5.8-5.8a2.789,2.789,0,0,1,3.942,0l.893.892A1,1,0,0,0,14.94,9.952l-.893-.892a4.791,4.791,0,0,0-6.771,0l-5.8,5.8a4.787,4.787,0,0,0,0,6.77l.892.891a4.785,4.785,0,0,0,6.771,0l2.736-2.735a1,1,0,1,0-1.414-1.415Z\"\/><path d=\"M22.526,2.363l-.892-.892a4.8,4.8,0,0,0-6.77,0l-2.905,2.9a1,1,0,0,0,1.414,1.414l2.9-2.9a2.79,2.79,0,0,1,3.941,0l.893.893a2.786,2.786,0,0,1,0,3.942l-5.8,5.8a2.769,2.769,0,0,1-1.971.817h0a2.766,2.766,0,0,1-1.969-.816,1,1,0,1,0-1.415,1.412,4.751,4.751,0,0,0,3.384,1.4h0a4.752,4.752,0,0,0,3.385-1.4l5.8-5.8a4.786,4.786,0,0,0,0-6.771Z\"\/><\/g><\/svg><\/a><strong>Receiving Ether \/ the fallback function<br \/>\n<\/strong><\/h2>\n<p>If you want your contract to receive Ether via the regular send() call, you have to make its fallback function cheap. It can only use 2300, gas which neither allows any storage write nor function calls that send along Ether. Basically the only thing you should do inside the fallback function is log an event so that external processes can react on the fact. Of course any function of a contract can receive ether and is not tied to that gas restriction. Functions actually have to reject Ether sent to them if they do not want to receive any, but we are thinking about potentially inverting this behaviour in some future release.<\/p><\/div>\n<p><br \/>\n<br \/><a href=\"https:\/\/blog.ethereum.org\/en\/2016\/06\/10\/smart-contract-security\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Solidity was started in October 2014 when neither the Ethereum network nor the virtual machine had any real-world testing, the gas costs at that time were even drastically different from what they are now. Furthermore, some of the early design decisions were taken over from Serpent. During the last couple of months, examples and patterns [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":20792,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"tdm_status":"","tdm_grid_status":"","footnotes":""},"categories":[24],"tags":[],"kronos_expire_date":[],"class_list":["post-22231","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ethereum"],"_links":{"self":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts\/22231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/comments?post=22231"}],"version-history":[{"count":0,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/posts\/22231\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/media\/20792"}],"wp:attachment":[{"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/media?parent=22231"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/categories?post=22231"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/tags?post=22231"},{"taxonomy":"kronos_expire_date","embeddable":true,"href":"https:\/\/cryptoted.net\/index.php\/wp-json\/wp\/v2\/kronos_expire_date?post=22231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}