{"id":19915478,"url":"https://github.com/demining/dao-exploit","last_synced_at":"2025-06-26T20:11:04.718Z","repository":{"id":200498478,"uuid":"657767332","full_name":"demining/Dao-Exploit","owner":"demining","description":"Cryptanalysis of the DAO exploit \u0026 Multi-Stage Attack","archived":false,"fork":false,"pushed_at":"2024-04-03T01:59:23.000Z","size":2260,"stargazers_count":18,"open_issues_count":1,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-07T11:37:24.164Z","etag":null,"topics":["attack","cryptanalysis","crypto","cryptocurrency","cryptography","dao","ethereum","ethereum-contract","exploit","exploit-development","hacking"],"latest_commit_sha":null,"homepage":"https://cryptodeeptech.ru/dao-exploit","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/demining.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-23T20:02:10.000Z","updated_at":"2025-03-12T07:04:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"f7889ebd-1df9-4f6f-b989-53b142286d2d","html_url":"https://github.com/demining/Dao-Exploit","commit_stats":null,"previous_names":["demining/dao-exploit"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/demining/Dao-Exploit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demining%2FDao-Exploit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demining%2FDao-Exploit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demining%2FDao-Exploit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demining%2FDao-Exploit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/demining","download_url":"https://codeload.github.com/demining/Dao-Exploit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/demining%2FDao-Exploit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262137149,"owners_count":23264675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["attack","cryptanalysis","crypto","cryptocurrency","cryptography","dao","ethereum","ethereum-contract","exploit","exploit-development","hacking"],"created_at":"2024-11-12T21:40:15.205Z","updated_at":"2025-06-26T20:11:04.694Z","avatar_url":"https://github.com/demining.png","language":"JavaScript","readme":"\n\u003cfigure class=\"aligncenter size-large\"\u003e\u003cimg decoding=\"async\" width=\"1024\" height=\"576\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/044-1024x576.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2342\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-1024x576.png 1024w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-300x169.png 300w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-768x432.png 768w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/044.png 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"\u003e\u003c/figure\u003e\u003c/div\u003e\n\n\n\u003cp\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003eIn this article, we will look at a bug in the DAO code. The hacker exploited a bug in the code of the DAO and stole more or less $50 million worth of ether. I will focus here only on the main technical issue of the exploit: The fallback function. For a more detailed and advanced recount of the attack, the blog posts by\u0026nbsp;Phil Daian\u0026nbsp;and\u0026nbsp;Peter Vessenes\u0026nbsp;are highly recommended.\u003c/p\u003e\n\n\n\n\u003cp\u003eThis post will be the first in what is potentially a series, deconstructing and explaining what went wrong at the technical level while providing a timeline tracing the actions of the attacker back through the blockchain. This first post will focus on\u0026nbsp;\u003cem\u003ehow\u003c/em\u003e\u0026nbsp;exactly the attacker stole all the money in the DAO.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eA Multi-Stage Attack\u003c/h2\u003e\n\n\n\n\u003cp\u003eThis exploit in the DAO is clearly not trivial; the exact programming pattern that made the DAO vulnerable was not only known, but\u0026nbsp;\u003ca href=\"https://blog.slock.it/no-dao-funds-at-risk-following-the-ethereum-smart-contract-recursive-call-bug-discovery-29f482d348b\"\u003efixed by the DAO creators themselves in an earlier intended update to the framework’s code\u003c/a\u003e. Ironically, as they were writing their blog posts and claiming victory, the hacker was preparing and deploying an exploit that targeted the same function they had just fixed to drain the DAO of all its funds.\u003c/p\u003e\n\n\n\n\u003cp\u003eLet’s get into the overview of the attack. The attacker was analyzing DAO.sol, and noticed that the ‘splitDAO’ function was vulnerable to the recursive send pattern we’ve described above: this function updates user balances and totals at the end, so if we can get any of the function calls before this happens to call splitDAO again, we get the infinite recursion that can be used to move as many funds as we want (code comments are marked with XXXXX, you may have to scroll to see em):\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction splitDAO(\n  uint _proposalID,\n  address _newCurator\n) noEther onlyTokenholders returns (bool _success) {\n\n  ...\n  // XXXXX Move ether and assign new Tokens.  Notice how this is done first!\n  uint fundsToBeMoved =\n      (balances[msg.sender] * p.splitData[0].splitBalance) /\n      p.splitData[0].totalSupply;\n  if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false) // XXXXX This is the line the attacker wants to run more than once\n      throw;\n\n  ...\n  // Burn DAO Tokens\n  Transfer(msg.sender, 0, balances[msg.sender]);\n  withdrawRewardFor(msg.sender); // be nice, and get his rewards\n  // XXXXX Notice the preceding line is critically before the next few\n  totalSupply -= balances[msg.sender]; // XXXXX AND THIS IS DONE LAST\n  balances[msg.sender] = 0; // XXXXX AND THIS IS DONE LAST TOO\n  paidOut[msg.sender] = 0;\n  return true;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eThe basic idea is this: propose a split. Execute the split. When the DAO goes to withdraw your reward, call the function to execute a split before that withdrawal finishes. The function will start running\u0026nbsp;\u003cstrong\u003ewithout updating your balance\u003c/strong\u003e, and the line we marked above as “the attacker wants to run more than once” will run more than once. What does that do? Well, the source code is in\u0026nbsp;\u003ca href=\"https://github.com/slockit/DAO/blob/v1.0/TokenCreation.sol\"\u003eTokenCreation.sol\u003c/a\u003e, and it transfers tokens from the parent DAO to the child DAO. Basically the attacker is using this to transfer more tokens than they should be able to into their child DAO.\u003c/p\u003e\n\n\n\n\u003cp\u003eHow does the DAO decide how many tokens to move? Using the balances array of course:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003euint fundsToBeMoved = (balances[msg.sender] * p.splitData[0].splitBalance) / p.splitData[0].totalSupply;\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eBecause p.splitData[0] is going to be the same every time the attacker calls this function (it’s a property of the proposal p, not the general state of the DAO), and because the attacker can call this function from withdrawRewardFor\u0026nbsp;\u003cstrong\u003ebefore the balances array is updated\u003c/strong\u003e, the attacker can get this code to run arbitrarily many times using the described attack, with fundsToBeMoved coming out to the same value each time.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe first thing the attacker needed to do to pave the way for his successful exploit was to have the withdraw function for the DAO, which was vulnerable to the critical recursive send exploit, actually run. Let’s look at what’s required to make that happen in code (from DAO.sol):\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction withdrawRewardFor(address _account) noEther internal returns (bool _success) {\n  if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply \u0026lt; paidOut[_account])\n    throw;\n\n  uint reward =\n    (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];\n  if (!rewardAccount.payOut(_account, reward)) // XXXXX vulnerable\n    throw;\n  paidOut[_account] += reward;\n  return true;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eIf the hacker could get the first if statement to evaluate to false, the statement marked vulnerable would run. When that statements runs, code that looks like this would be called:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction payOut(address _recipient, uint _amount) returns (bool) {\n  if (msg.sender != owner || msg.value \u0026gt; 0 || (payOwnerOnly \u0026amp;\u0026amp; _recipient != owner))\n      throw;\n  if (_recipient.call.value(_amount)()) { // XXXXX vulnerable\n      PayOut(_recipient, _amount);\n      return true;\n  } else {\n      return false;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eNotice how the marked line is exactly the vulnerable code mentioned in the\u0026nbsp;\u003ca href=\"http://vessenes.com/more-ethereum-attacks-race-to-empty-is-the-real-deal/\"\u003edescription of the exploit\u003c/a\u003e\u0026nbsp;we linked!\u003c/p\u003e\n\n\n\n\u003cp\u003eThat line would then send a message from the DAO’s contract to “_recipient” (the attacker). “_recipient” would of course contain a default function, that would call splitDAO again with the same parameters as the initial call from the attacker. Remember that because this is all happening from inside withdrawFor from inside splitDAO, the code updating the balances in splitDAO hasn’t run. So the split will send more tokens to the child DAO, and then ask for the reward to be withdrawn again. Which will try to send tokens to “_recipient” again, which would again call split DAO before updating the balances array.\u003c/p\u003e\n\n\n\n\u003cp\u003eAnd so it goes:\u003c/p\u003e\n\n\n\n\u003col\u003e\n\u003cli\u003ePropose a split and wait until the voting period expires.\u0026nbsp;\u003cem\u003e(DAO.sol, createProposal)\u003c/em\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003eExecute the split.\u0026nbsp;\u003cem\u003e(DAO.sol, splitDAO)\u003c/em\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003eLet the DAO send your new DAO its share of tokens.\u0026nbsp;\u003cem\u003e(splitDAO -\u0026gt; TokenCreation.sol, createTokenProxy)\u003c/em\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003eMake sure the DAO tries to send you a reward before it updates your balance but after doing (3).\u0026nbsp;\u003cem\u003e(splitDAO -\u0026gt; withdrawRewardFor -\u0026gt; ManagedAccount.sol, payOut)\u003c/em\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003eWhile the DAO is doing (4), have it run splitDAO again with the same parameters as in (2)\u0026nbsp;\u003cem\u003e(payOut -\u0026gt; _recipient.call.value -\u0026gt; _recipient())\u003c/em\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003eThe DAO will now send you more child tokens, and go to withdraw your reward before updating your balance.\u0026nbsp;\u003cem\u003e(DAO.sol, splitDAO)\u003c/em\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003eBack to (5)!\u003c/li\u003e\n\n\n\n\u003cli\u003eLet the DAO update your balance. Because (7) goes back to (5), it never actually will :-).\u003c/li\u003e\n\u003c/ol\u003e\n\n\n\n\u003cp\u003e(Side note: Ethereum’s gas mechanics don’t save us here. call.value passes on all the gas a transaction is working with by default, unlike the send function. so the code will run as long as the attacker will pay for it, which considering it’s a cheap exploit means indefinitely)\u003c/p\u003e\n\n\n\n\u003cp\u003eArmed with this, we can provide a step by step re-trace of how The DAO got emptied out.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eStep 1: Proposing the Split\u003c/h2\u003e\n\n\n\n\u003cp\u003eThe first step towards all of the above is to simply propose a regular split, as we’ve mentioned.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe attacker does this in the blockchain\u0026nbsp;\u003ca href=\"https://live.ether.camp/transaction/5798fbc45e3b63832abc4984b0f3574a13545f415dd672cd8540cd71f735db56\"\u003ehere\u003c/a\u003e\u0026nbsp;in DAO Proposal #59, with the title “Lonely, so Lonely”.\u003c/p\u003e\n\n\n\n\u003cp\u003eBecause of this line:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003e// The minimum debate period that a split proposal can have\nuint constant minSplitDebatePeriod = 1 weeks;\n\u003c/pre\u003e\n\n\n\n\u003cp\u003ehe had to wait a week for the proposal to see approval. No matter, it’s just a split proposal like any other! Nobody will look too closely at it, right?\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eStep 2: Getting the Reward\u003c/h2\u003e\n\n\n\n\u003cp\u003eAs was neatly explained in one of\u0026nbsp;\u003ca href=\"https://blog.slock.it/no-dao-funds-at-risk-following-the-ethereum-smart-contract-recursive-call-bug-discovery-29f482d348b\"\u003eslock.it’s previous posts on the matter\u003c/a\u003e, there are no rewards for the DAO to give out yet! (because no rewards were generated).\u003c/p\u003e\n\n\n\n\u003cp\u003eAs we mentioned in the overview, the critical lines that need to run here are:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction withdrawRewardFor(address _account) noEther internal returns (bool _success) {\n  if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply \u0026lt; paidOut[_account]) // XXXXX\n    throw;\n\n  uint reward =\n    (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];\n  if (!rewardAccount.payOut(_account, reward)) // XXXXX\n    throw;\n  paidOut[_account] += reward;\n  return true;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eIf the hacker could get the first marked line to run, the second marked line will run the default function of his choosing (that calls back to splitDAO as we described previously).\u003c/p\u003e\n\n\n\n\u003cp\u003eLet’s deconstruct the first if statement:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003eif ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply \u0026lt; paidOut[_account])\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eThe balanceOf function is defined in\u0026nbsp;\u003ca href=\"https://github.com/slockit/DAO/blob/develop/Token.sol\"\u003eToken.sol\u003c/a\u003e, and of course does exactly this:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003ereturn balances[_owner];\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eThe rewardAccount.accumulatedInput() line is evaluated from code in\u0026nbsp;\u003ca href=\"https://github.com/slockit/DAO/blob/v1.0/ManagedAccount.sol\"\u003eManagedAccount.sol\u003c/a\u003e:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003e// The sum of ether (in wei) which has been sent to this contract\nuint public accumulatedInput;\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eLuckily accumulatedInput is oh so simple to manipulate. Just use the default function of the reward account!\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction() {\n    accumulatedInput += msg.value;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eNot only that, but because there is no logic to decrease accumulatedInput anywhere (it tracks the input the account has gotten from all the transactions ever), all the attacker needs to do is send a few Wei to the reward account and our original condition will not only evaluate to false, but its constituent values will evaluate to the same thing every time it’s called:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003eif ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply \u0026lt; paidOut[_account])\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eRemember that because balanceOf refers to balances, which never gets updated, and because paidOut and totalSupply also never get updated since that code in splitDAO never actually executes, the attacker gets to claim their tiny share of the reward with no problems. And because they can claim their share of the reward, they can run their default function and reenter back to splitDAO. Whoopsie.\u003c/p\u003e\n\n\n\n\u003cp\u003eBut do they actually need to include a reward? Let’s look at the line again:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003eif ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply \u0026lt; paidOut[_account])\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eWhat if the reward account balance is 0? Then we get\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003eif (0 \u0026lt; paidOut[_account])\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eIf nothing has ever been paid out, this will always evaluate to false and never throw! Why? The original line is equivalent, after subtracting paidOut from both sides, to:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003eif ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account] \u0026lt; 0)\n\u003c/pre\u003e\n\n\n\n\u003cp\u003ewhere that first part is actually how much is being paid out. So the check is actually:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003eif (amountToBePaid \u0026lt; 0)\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eBut if amountToBePaid is 0,\u0026nbsp;\u003cstrong\u003ethe DAO pays you anyway\u003c/strong\u003e. To me this doesn’t make much sense — why waste the gas in this manner? I think this is why many people assumed the attacker needed a balance in the reward account to proceed with the attack, something they in fact did not require. The attack works the same way with an empty reward account as with a full one!\u003c/p\u003e\n\n\n\n\u003cp\u003eLet’s take a look at the DAO’s reward address. The DAO accounting documentation from Slockit pegs this address as\u0026nbsp;\u003ca href=\"https://github.com/slockit/DAO/wiki/Understanding-the-DAO-accounting\"\u003e0xd2e16a20dd7b1ae54fb0312209784478d069c7b0\u003c/a\u003e.\u0026nbsp;\u003ca href=\"https://etherscan.io/txsInternal?a=0xd2e16a20dd7b1ae54fb0312209784478d069c7b0\u0026amp;\u0026amp;zero=true\u0026amp;p=220\"\u003eCheck that account’s transactions\u003c/a\u003e\u0026nbsp;and you see a pattern: 200 pages of .00000002 ETH transactions to\u0026nbsp;\u003ca href=\"http://etherscan.io/address/0xf835a0247b0063c04ef22006ebe57c5f11977cc4\"\u003e0xf835a0247b0063c04ef22006ebe57c5f11977cc4\u003c/a\u003e\u0026nbsp;and\u0026nbsp;\u003ca href=\"https://etherscan.io/address/0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89\"\u003e0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89\u003c/a\u003e, the attacker’s two malicious contracts (which we cover later). That’s one transaction for each recursive call of withdrawRewardFor, which we described above. So in this case there actually was a balance in the rewards account, and the attacker gets to collect some dust.\u003c/p\u003e\n\n\n\u003cdiv class=\"wp-block-image\"\u003e\n\u003cfigure class=\"aligncenter size-full\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" width=\"876\" height=\"438\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-48.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2338\"\u003e\u003c/figure\u003e\u003c/div\u003e\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eStep 3: The Big Short\u003c/h2\u003e\n\n\n\n\u003cp\u003eA number of\u0026nbsp;\u003ca href=\"https://www.reddit.com/r/ethereum/comments/4olfhh/finding_the_hacker_through_analysis_of_shorts_on\"\u003eentirely unsubstantiated allegations\u003c/a\u003e\u0026nbsp;on social media have pointed to a $3M Ethereum short that occurred on Bitfinex just moments before the attack, claiming this short closed with almost $1M USD of profit.\u003c/p\u003e\n\n\n\n\u003cp\u003eIt’s obvious to anyone constructing or analyzing this attack that certain properties of the DAO (specifically that any split must be running the same code as the original DAO) require an attacker to wait through the creation period of their child DAO (27 days) before withdrawing any coins in a malicious split. This gives the community time to respond to a theft, through either a soft fork freezing attacker funds or a hard fork rolling back the compromise entirely.\u003c/p\u003e\n\n\n\n\u003cp\u003eAny financially motivated attacker who had attempted their exploit on the testnet would have an incentive to ensure profits regardless of a potential rollback or fork by shorting the underlying token. The\u0026nbsp;\u003ca href=\"http://www.businessinsider.com/dao-hacked-ethereum-crashing-in-value-tens-of-millions-allegedly-stolen-2016-6?r=UK\u0026amp;amp;IR=T\"\u003estaggering drop\u003c/a\u003e\u0026nbsp;that resulted within minutes of the smart contract that triggered the malicious split provided an excellent profit opportunity, and while there is no proof the attacker took the profit opportunity, we can at least conclude that after all this effort they would have been stupid not to.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eStep 3a: Preventing Exit (Resistance is Futile)\u003c/h2\u003e\n\n\n\n\u003cp\u003eAnother contingency that the attacker needed to think of is the case that a DAO split occurs before the attacker can finish emptying the DAO. In this case, with another user as sole curator, the attacker would have no access to DAO funds.\u003c/p\u003e\n\n\n\n\u003cp\u003eUnfortunately the attacker is a smart guy:\u0026nbsp;\u003ca href=\"https://www.reddit.com/r/ethereum/comments/4okekv/split_daos_vulnerable_to_hack/\"\u003ethere is evidence\u003c/a\u003e\u0026nbsp;that the attacker has voted yes on all split proposals that come to term after his own, making sure that he would hold some tokens in the case of any DAO split. Because of a property of the DAO we’ll discuss later in the post, these split DAOs are vulnerable to the same emptying attack we’re describing here. All the attacker has to do is sit through the creation period, send some Ether to the reward account, and propose and execute a split by himself away from this new DAO. If he can execute before the curator of this new DAO updates the code to remove the vulnerability, he manages to squash all attempts to get Ether out of the DAO that aren’t his own.\u003c/p\u003e\n\n\n\n\u003cp\u003eNotice by the timestamps here that the attacker did this right around the time he started the malicious split, almost as an afterthought. I see this more as an unnecessary middle finger to the DAO than a financially viable attack: having already emptied virtually the entire DAO, going through this effort to pick up any pennies that might be left on the table is probably an attempt to demoralize holders into inaction. Many have concluded, and I agree, that this hints at the attacker’s motivations being a complete destruction of the DAO that goes beyond profit taking. While none of us know the truth here, I do recommend applying your own judgment.\u003c/p\u003e\n\n\n\n\u003cp\u003eInterestingly enough, this attack was\u0026nbsp;\u003ca href=\"http://hackingdistributed.com/2016/06/17/thoughts-on-the-dao-hack/\"\u003edescribed by Emin Gün Sirer\u003c/a\u003e\u0026nbsp;after it had already occurred on the blockchain, but before the public had noticed.\u003c/p\u003e\n\n\n\u003cdiv class=\"wp-block-image\"\u003e\n\u003cfigure class=\"aligncenter size-full\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" width=\"1344\" height=\"681\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-49.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2339\"\u003e\u003c/figure\u003e\u003c/div\u003e\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eStep 4: Executing the Split\u003c/h2\u003e\n\n\n\n\u003cp\u003eSo we’ve painstakingly described all the boring technical aspects of this attack. Let’s get to the fun part, the action: executing the malicious split. The account that executed the transactions behind the split is\u0026nbsp;\u003ca href=\"http://etherscan.io/address/0xf35e2cc8e6523d683ed44870f5b7cc785051a77d\"\u003e0xf35e2cc8e6523d683ed44870f5b7cc785051a77d\u003c/a\u003e.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe child DAO they sent funds to is\u0026nbsp;\u003ca href=\"http://etherscan.io/address/0x304a554a310c7e546dfe434669c62820b7d83490\"\u003e0x304a554a310c7e546dfe434669c62820b7d83490\u003c/a\u003e. The proposal was created and initiated by account\u0026nbsp;\u003ca href=\"https://live.ether.camp/account/b656b2a9c3b2416437a811e07466ca712f5a5b5a\"\u003e0xb656b2a9c3b2416437a811e07466ca712f5a5b5a\u003c/a\u003e\u0026nbsp;(you can see the call to createProposal in the blockchain history there).\u003c/p\u003e\n\n\n\n\u003cp\u003eDeconstructing the constructor arguments that created that child DAO leads us to a curator at\u0026nbsp;\u003ca href=\"https://live.ether.camp/account/da4a4626d3e16e094de3225a751aab7128e96526/contract\"\u003e0xda4a4626d3e16e094de3225a751aab7128e96526\u003c/a\u003e. That smart contract is just a regular multisignature wallet, with most of its past transactions being adding/removing owners and other wallet management tasks. Nothing interesting there.\u003c/p\u003e\n\n\n\n\u003cp\u003eJohannes Pfeffer on Medium\u0026nbsp;\u003ca href=\"https://medium.com/@oaeee/the-rise-of-the-dark-dao-72b21a2212e3#.rnb1n01h8\"\u003ehas an excellent blockchain-based reconstruction\u003c/a\u003e\u0026nbsp;of the transactions involved in the malicious Child DAO. I won’t spend too much time on such blockchain analysis, since he’s already done a great job. I highly encourage anyone interested to start with that article.\u003c/p\u003e\n\n\n\n\u003cp\u003eIn the next article in the series, we’ll look at the code from the malicious contract itself (containing the exploit that actually launched the recursive attack). In the interest of expedience of release, we have not yet completed such an analysis.\u003c/p\u003e\n\n\n\u003cdiv class=\"wp-block-image\"\u003e\n\u003cfigure class=\"aligncenter size-large\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"648\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-47-1024x648.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2337\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-47-1024x648.png 1024w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-47-300x190.png 300w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-47-768x486.png 768w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-47.png 1081w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"\u003e\u003c/figure\u003e\u003c/div\u003e\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eStep 4a: Extending the Split\u003c/h2\u003e\n\n\n\n\u003cp\u003eThis step is an update to the original update, and covers how the attacker was able to turn a ~30X amplification attack (due to the max size of Ethereum’s stack being capped at 128) to a virtually infinite draining account.\u003c/p\u003e\n\n\n\n\u003cp\u003eSavvy readers of the above may notice that, even after overwhelming the stack and executing many more malicious splits than was required, the hacker would have their balance zeroed out by the code at the end of splitDAO:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction splitDAO(\n  ....\n  withdrawRewardFor(msg.sender); // be nice, and get his rewards\n  totalSupply -= balances[msg.sender];\n  balances[msg.sender] = 0;\n  paidOut[msg.sender] = 0;\n  return true;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eSo how did the attacker get around this? Thanks to the ability to transfer DAO tokens, he didn’t really need to! All he had to do was call the DAO’s helpful\u0026nbsp;\u003ca href=\"https://github.com/slockit/DAO/blob/v1.0/Token.sol#L92\"\u003etransfer\u003c/a\u003e\u0026nbsp;function at the top of his stack, from his malicious function:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction ​transfer(address _to, uint256 _amount) noEther returns (bool success) {\n ​if (balances[msg.sender] \u0026gt;= _amount \u0026amp;\u0026amp; _amount \u0026gt; 0) {\n   ​balances[msg.sender] -= _amount;\n   ​balances[_to] += _amount;\n   ​...\u003c/pre\u003e\n\n\n\n\u003cp\u003eBy transferring the tokens to a proxy account, the original account would be zeroed out correctly at the end of splitDAO (notice how if A transfers all its money to B, A’s account is already zeroed out by transfer before it can be zeroed out by splitDAO). The attacker can then send the money back from the proxy account to the original account and start the whole process again. Even the update to totalSupply in splitDAO is missed, since p.totalSupply[0] is used to calculate the payout, which is a property of the original proposal and only instantiated once before the attack occurs. So the attack size stays constant despite less available ETH in the DAO with every iteration.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe evidence of two malicious contracts calling into withdrawRewardFor on the blockchain suggests that the attacker’s proxy account was also an attack-enabled contract that simply alternated as the attacker with the original contract. This optimization saves the attacker one transaction per attack cycle, but otherwise appears unnecessary.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eWas 1.1 Vulnerable?\u003c/h2\u003e\n\n\n\n\u003cp\u003eBecause this vulnerability was in withdrawRewardFor, a natural question to ask is whether the DAO 1.1, with the updated function, was still vulnerable to a similar attack. The answer:\u0026nbsp;\u003cstrong\u003eyes\u003c/strong\u003e.\u003c/p\u003e\n\n\n\n\u003cp\u003eCheck out the updated function (especially the marked lines):\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003efunction withdrawRewardFor(address _account) noEther internal returns (bool _success) {\n  if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply \u0026lt; paidOut[_account])\n    throw;\n\n  uint reward =\n    (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];\n\n  reward = rewardAccount.balance \u0026lt; reward ? rewardAccount.balance : reward;\n\n  paidOut[_account] += reward; // XXXXX\n  if (!rewardAccount.payOut(_account, reward)) // XXXXX\n    throw;\n\n  return true;\n}\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eNotice how paidOut is updated before the actual payout is made now. So how does this affect our exploit? Well, the second time getRewardFor is called, from inside the evil second call to splitDAO, this line:\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003euint reward =\n (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];\n\u003c/pre\u003e\n\n\n\n\u003cp\u003ewill come out to 0. The payOut call will then call _recipient.call.value(0)(), which is the default value for that function, making it equivalent to a call to\u003c/p\u003e\n\n\n\n\u003cpre class=\"wp-block-preformatted\"\u003e_recipient.call()\n\u003c/pre\u003e\n\n\n\n\u003cp\u003eBecause the attacker paid for a lot of gas when sending his malicious split transaction, the recursive attack is allowed to continue with a vengeance.\u003c/p\u003e\n\n\n\n\u003cp\u003eRealizing they needed a 1.2 6 days after a 1.1, on code designed to be secure for years, is probably why the DAO’s puppet masters called it quits.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eAn Important Takeaway\u003c/h2\u003e\n\n\n\n\u003cp\u003eI think the susceptibility of 1.1 to this attack is really interesting: even though withdrawReward for was not vulnerable by itself, and even though splitDAO was not vulnerable without withdrawRewardFor, the combination proves deadly. This is probably why this exploit was missed in review so many times by so many different people: reviewers tend to review functions one at a time, and assume that calls to secure subroutines will operate securely and as intended.\u003c/p\u003e\n\n\n\n\u003cp\u003eIn the case of Ethereum, even secure functions that involve sending funds could render your original function as vulnerable to reentrancy. Whether they’re functions from the default Solidity libraries or functions that you wrote yourself with security in mind. Special care is required in reviews of Ethereum code to make sure that any functions moving value occur after any state updates whatsoever, otherwise these state values will be necessarily vulnerable to reentrancy.\u003c/p\u003e\n\n\n\n\u003cp\u003eI won’t cover the fork debate or what’s next for Ethereum and The DAO here. That subject is being beaten to death on every form of social media imaginable.\u003c/p\u003e\n\n\n\n\u003cp\u003eFor our series of posts, the next step is to reconstruct the exploit on the TestNet using the DAO 1.0 code, and demonstrate both the code behind the exploit and the mechanism of attack. Please note that if someone beats me to these objectives, I reserve the right to cap the length of the series at one.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eSolidity\u003c/h2\u003e\n\n\n\n\u003cp\u003eSolidity is an object-oriented, high-level language for implementing smart contracts. Smart contracts are programs that govern the behavior of accounts within the Ethereum state.\u003c/p\u003e\n\n\n\n\u003cp\u003eSolidity is a\u0026nbsp;\u003ca href=\"https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages\"\u003ecurly-bracket language\u003c/a\u003e\u0026nbsp;designed to target the Ethereum Virtual Machine (EVM). It is influenced by C++, Python, and JavaScript. You can find more details about which languages Solidity has been inspired by in the\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id1\"\u003e:doc:`language influences \u0026lt;language-influences\u0026gt;`\u003c/a\u003e\u0026nbsp;section.\u003c/p\u003e\n\n\n\n\u003cp\u003eSolidity is statically typed, supports inheritance, libraries, and complex user-defined types, among other features.\u003c/p\u003e\n\n\n\n\u003cp\u003eWith Solidity, you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets.\u003c/p\u003e\n\n\n\n\u003cp\u003eWhen deploying contracts, you should use the latest released version of Solidity. Apart from exceptional cases, only the latest version receives\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/security/policy#supported-versions\"\u003esecurity fixes\u003c/a\u003e. Furthermore, breaking changes, as well as new features, are introduced regularly. We currently use a 0.y.z version number\u0026nbsp;\u003ca href=\"https://semver.org/#spec-item-4\"\u003eto indicate this fast pace of change\u003c/a\u003e.\u003c/p\u003e\n\n\n\n\u003cp\u003eWarning\u003c/p\u003e\n\n\n\n\u003cp\u003eSolidity recently released the 0.8.x version that introduced a lot of breaking changes. Make sure you read\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id3\"\u003e:doc:`the full list \u0026lt;080-breaking-changes\u0026gt;`\u003c/a\u003e.\u003c/p\u003e\n\n\n\n\u003cp\u003eIdeas for improving Solidity or this documentation are always welcome, read our\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id5\"\u003e:doc:`contributors guide \u0026lt;contributing\u0026gt;`\u003c/a\u003e\u0026nbsp;for more details.\u003c/p\u003e\n\n\n\n\u003cp\u003eHint\u003c/p\u003e\n\n\n\n\u003cp\u003eYou can download this documentation as PDF, HTML or Epub by clicking on the versions flyout menu in the bottom-left corner and selecting the preferred download format.\u003ca\u003e\u003c/a\u003e\u003c/p\u003e\n\n\n\n\u003ch3 class=\"wp-block-heading\"\u003e\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#getting-started\"\u003e\u003c/a\u003eGetting Started\u003c/h3\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e1. Understand the Smart Contract Basics\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003eIf you are new to the concept of smart contracts, we recommend you to get started by digging into the “Introduction to Smart Contracts” section, which covers the following:\u003c/p\u003e\n\n\n\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id7\"\u003e:ref:`A simple example smart contract \u0026lt;simple-smart-contract\u0026gt;`\u003c/a\u003e\u0026nbsp;written in Solidity.\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id9\"\u003e:ref:`Blockchain Basics \u0026lt;blockchain-basics\u0026gt;`\u003c/a\u003e.\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id11\"\u003e:ref:`The Ethereum Virtual Machine \u0026lt;the-ethereum-virtual-machine\u0026gt;`\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e2. Get to Know Solidity\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003eOnce you are accustomed to the basics, we recommend you read the\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id13\"\u003e:doc:`”Solidity by Example” \u0026lt;solidity-by-example\u0026gt;`\u003c/a\u003e\u0026nbsp;and “Language Description” sections to understand the core concepts of the language.\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e3. Install the Solidity Compiler\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003eThere are various ways to install the Solidity compiler, simply choose your preferred option and follow the steps outlined on the\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id15\"\u003e:ref:`installation page \u0026lt;installing-solidity\u0026gt;`\u003c/a\u003e.\u003c/p\u003e\n\n\n\n\u003cp\u003eHint\u003c/p\u003e\n\n\n\n\u003cp\u003eYou can try out code examples directly in your browser with the\u0026nbsp;\u003ca href=\"https://remix.ethereum.org/\"\u003eRemix IDE\u003c/a\u003e. Remix is a web browser-based IDE that allows you to write, deploy and administer Solidity smart contracts, without the need to install Solidity locally.\u003c/p\u003e\n\n\n\n\u003cp\u003eWarning\u003c/p\u003e\n\n\n\n\u003cp\u003eAs humans write software, it can have bugs. Therefore, you should follow established software development best practices when writing your smart contracts. This includes code review, testing, audits, and correctness proofs. Smart contract users are sometimes more confident with code than their authors, and blockchains and smart contracts have their own unique issues to watch out for, so before working on production code, make sure you read the\u0026nbsp;\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#id17\"\u003e:ref:`security_considerations`\u003c/a\u003e\u0026nbsp;section.\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e4. Learn More\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003eIf you want to learn more about building decentralized applications on Ethereum, the\u0026nbsp;\u003ca href=\"https://ethereum.org/en/developers/\"\u003eEthereum Developer Resources\u003c/a\u003e\u0026nbsp;can help you with further general documentation around Ethereum, and a wide selection of tutorials, tools, and development frameworks.\u003c/p\u003e\n\n\n\n\u003cp\u003eIf you have any questions, you can try searching for answers or asking on the\u0026nbsp;\u003ca href=\"https://ethereum.stackexchange.com/\"\u003eEthereum StackExchange\u003c/a\u003e, or our\u0026nbsp;\u003ca href=\"https://gitter.im/ethereum/solidity\"\u003eGitter channel\u003c/a\u003e.\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003c/p\u003e\n\n\n\n\u003ch3 class=\"wp-block-heading\"\u003e\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#translations\"\u003e\u003c/a\u003eTranslations\u003c/h3\u003e\n\n\n\n\u003cp\u003eCommunity contributors help translate this documentation into several languages. Note that they have varying degrees of completeness and up-to-dateness. The English version stands as a reference.\u003c/p\u003e\n\n\n\n\u003cp\u003eYou can switch between languages by clicking on the flyout menu in the bottom-left corner and selecting the preferred language.\u003c/p\u003e\n\n\n\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://docs.soliditylang.org/zh/latest/\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eChinese\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://docs.soliditylang.org/fr/latest/\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eFrench\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/solidity-docs/id-indonesian\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eIndonesian\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/solidity-docs/ja-japanese\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eJapanese\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/solidity-docs/ko-korean\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eKorean\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/solidity-docs/fa-persian\" target=\"_blank\" rel=\"noreferrer noopener\"\u003ePersian\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/solidity-docs/ru-russian\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eRussian\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://github.com/solidity-docs/es-spanish\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eSpanish\u003c/a\u003e\u003c/li\u003e\n\n\n\n\u003cli\u003e\u003ca href=\"https://docs.soliditylang.org/tr/latest/\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eTurkish\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\n\n\u003cp\u003eNote\u003c/p\u003e\n\n\n\n\u003cp\u003eWe set up a GitHub organization and translation workflow to help streamline the community efforts. Please refer to the translation guide in the\u0026nbsp;\u003ca href=\"https://github.com/solidity-docs\"\u003esolidity-docs org\u003c/a\u003e\u0026nbsp;for information on how to start a new language or contribute to the community translations.\u003ca\u003e\u003c/a\u003e\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003e\u003ca href=\"https://github.com/ethereum/solidity/blob/develop/docs/index.rst#contents\"\u003e\u003c/a\u003eContents\u003c/h2\u003e\n\n\n\n\u003cfigure class=\"wp-block-image size-full is-resized\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-44.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2332\" width=\"839\" height=\"438\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-44.png 452w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-44-300x157.png 300w\" sizes=\"(max-width: 839px) 100vw, 839px\"\u003e\u003c/figure\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003cfigure class=\"wp-block-image size-full is-resized\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-43.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2331\" width=\"839\" height=\"715\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-43.png 432w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-43-300x256.png 300w\" sizes=\"(max-width: 839px) 100vw, 839px\"\u003e\u003c/figure\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003cfigure class=\"wp-block-image size-full is-resized\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-45.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2333\" width=\"840\" height=\"1033\"\u003e\u003c/figure\u003e\n\n\n\n\u003cfigure class=\"wp-block-image size-full is-resized\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-46.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2334\" width=\"841\" height=\"1026\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-46.png 477w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-46-246x300.png 246w\" sizes=\"(max-width: 841px) 100vw, 841px\"\u003e\u003c/figure\u003e\n\n\n\n\u003cp\u003e\u003c/p\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003ch1 class=\"wp-block-heading\" id=\"0ff1\"\u003eBasic concepts\u003c/h1\u003e\n\n\n\n\u003cp id=\"8998\"\u003eTo start off, keep in mind that in Ethereum there are two types of accounts: (i) externally owned accounts controlled by humans and (ii) contract accounts controlled by code.\u0026nbsp;\u003cmark\u003eThis is important because only contract accounts have associated code, and hence, can have a fallback function.\u003c/mark\u003e\u003c/p\u003e\n\n\n\n\u003cp id=\"ede9\"\u003eIn Ethereum all the action is triggered by transactions or messages (calls) set off by externally owned accounts. Those transactions can be an ether transfer or the triggering of contract code. Remember, contracts can trigger other contracts’ code as well.\u003c/p\u003e\n\n\n\n\u003cp id=\"b9a3\"\u003eSmart contracts are written in high-level programming languages such as\u0026nbsp;\u003ca href=\"https://solidity.readthedocs.io/en/develop/\" rel=\"noreferrer noopener\" target=\"_blank\"\u003eSolidity\u003c/a\u003e\u0026nbsp;but for those contracts to be uploaded on the blockchain, they need to be compiled into\u0026nbsp;\u003ca href=\"https://en.wikipedia.org/wiki/Bytecode\" rel=\"noreferrer noopener\" target=\"_blank\"\u003ebytecode\u003c/a\u003e, a low-level programming language executed by the Ethereum Virtual Machine (EVM). Said bytecode can be interpreted with\u0026nbsp;\u003ca href=\"https://ethereum.gitbooks.io/frontier-guide/content/opcodes,_costs,_and_gas.html\" rel=\"noreferrer noopener\" target=\"_blank\"\u003eopcodes\u003c/a\u003e.\u003c/p\u003e\n\n\n\n\u003cp id=\"458d\"\u003eWhen a contract calls or sends money to another contract that code compiles in the EVM bytecode, invoking the call function. But, there is a difference: When calling another contract the call function provides specific function identifiers and data, however, when sending money to another contract, the call function has a set amount of\u0026nbsp;\u003ca href=\"http://ethdocs.org/en/latest/contracts-and-transactions/account-types-gas-and-transactions.html#what-is-gas\" rel=\"noreferrer noopener\" target=\"_blank\"\u003egas\u003c/a\u003e\u0026nbsp;but no data (case b below), and thus, triggers the fallback function of the called contract.\u003c/p\u003e\n\n\n\n\u003ch1 class=\"wp-block-heading\" id=\"3e81\"\u003eThe attack\u003c/h1\u003e\n\n\n\n\u003cp id=\"66ee\"\u003eThe fallback function abuse played a very important role in the DAO attack. Let’s see what a fallback function is and how it can be used for malicious purposes.\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\" id=\"05d3\"\u003eFallback function\u003c/h2\u003e\n\n\n\n\u003cp id=\"7c41\"\u003eA contract can have one anonymous function, known as well as the fallback function. This function does not take any arguments and it is triggered in three cases [1]:\u003c/p\u003e\n\n\n\n\u003cp id=\"7ead\"\u003ea. If none of the functions of the call to the contract match any of the functions in the called contract\u003c/p\u003e\n\n\n\n\u003cp id=\"d78a\"\u003eb. When the contract receives ether without extra data\u003c/p\u003e\n\n\n\n\u003cp id=\"b948\"\u003ec. If no data was supplied\u003c/p\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\" id=\"50b2\"\u003eExample\u003c/h2\u003e\n\n\n\n\u003cp id=\"aef1\"\u003eThe following is sample code for a contract vulnerable to a malicious fallback function of another contract. In this example we have two contracts: (i) the contract Bank (vulnerable contract) and (ii) the contract BankAttacker (malicious contract). Imagine that the contract Bank is the DAO smart contract but much more simplified and the contract BankAttacker is the hacker’s malicious smart contract that emptied the DAO.\u003c/p\u003e\n\n\n\n\u003cp id=\"c7bd\"\u003eThe hacker initiates the interaction with contract Bank through its malicious contract and the sequence of the actions is as follows:\u003c/p\u003e\n\n\n\n\u003col\u003e\n\u003cli\u003eThe first thing the hacker does is send ether (75 wei) to the vulnerable contract through the\u0026nbsp;\u003cem\u003edeposit\u003c/em\u003e\u0026nbsp;\u003cem\u003efunction\u0026nbsp;\u003c/em\u003eof the malicious contract. This function calls the\u0026nbsp;\u003cem\u003eaddToBalance function\u003c/em\u003e\u0026nbsp;of the vulnerable contract.\u003c/li\u003e\n\n\n\n\u003cli\u003eThen, the hacker withdraws, through the\u0026nbsp;\u003cem\u003ewithdraw function\u003c/em\u003e\u0026nbsp;of the malicious contract, the same amount of wei (75), triggering the\u0026nbsp;\u003cem\u003ewithdrawBalance\u003c/em\u003e\u0026nbsp;\u003cem\u003efunction\u0026nbsp;\u003c/em\u003eof the vulnerable contract.\u003c/li\u003e\n\n\n\n\u003cli\u003eThe\u0026nbsp;\u003cem\u003ewithdrawBalance function\u003c/em\u003e\u0026nbsp;first sends ether (75 wei) to the malicious contract, triggering its fallback function, and last updates the\u0026nbsp;\u003cem\u003euserBalances\u0026nbsp;\u003c/em\u003evariable\u003cem\u003e\u0026nbsp;\u003c/em\u003e(that this piece is done last is very important for the attack).\u003c/li\u003e\n\n\n\n\u003cli\u003eThe malicious fallback function calls the\u0026nbsp;\u003cem\u003ewithdrawBalance\u003c/em\u003e\u0026nbsp;\u003cem\u003efunction\u0026nbsp;\u003c/em\u003eagain (recursive call), doubling the withdraw, before the execution of the first\u0026nbsp;\u003cem\u003ewithdrawBalance function\u003c/em\u003e\u0026nbsp;finishes, and thus, without updating the\u0026nbsp;\u003cem\u003euserBalances\u003c/em\u003e\u0026nbsp;variable.\u003c/li\u003e\n\u003c/ol\u003e\n\n\n\n\u003cp id=\"615b\"\u003eIn this example, there are only two recursive calls to the\u0026nbsp;\u003cem\u003ewithdrawBalance function\u003c/em\u003e\u0026nbsp;so the hacker ends up with a balance of 150 wei. They took more than they should (75 wei) because the\u0026nbsp;\u003cem\u003euserBalance\u0026nbsp;\u003c/em\u003evariable is the last thing set/updated.\u003c/p\u003e\n\n\n\n\u003cp id=\"8bce\"\u003eOne important point is that unlike the JavaScript’s blocks of code, the EVM executes instructions\u0026nbsp;\u003ca href=\"http://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-does-it-really-mean\" rel=\"noreferrer noopener\" target=\"_blank\"\u003esynchronously\u003c/a\u003e, one after the other, and this is why the\u0026nbsp;\u003cem\u003euserBalance\u003c/em\u003e\u0026nbsp;variable is updated only after the previous code is finished.\u003c/p\u003e\n\n\n\n\u003cp id=\"0986\"\u003eThe following is a more graphic explanation of the example. The instances referred in this graphic are the different states of the contracts saved in the blockchain. In the graphic you will see that the hacker, through his/her/their external account, triggers the malicious contract, so this contract can interact with the vulnerable contract.\u003c/p\u003e\n\n\n\u003cdiv class=\"wp-block-image\"\u003e\n\u003cfigure class=\"aligncenter size-large\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"797\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-40-1024x797.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2324\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-40-1024x797.png 1024w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-40-300x233.png 300w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-40-768x598.png 768w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-40.png 1042w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"\u003e\u003c/figure\u003e\u003c/div\u003e\n\n\n\u003cp\u003eLast, here is the example in\u0026nbsp;JavaScript, just in case you are not very familiar with Solidity yet.\u003c/p\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003cp\u003eThe hacker stole over $100 million in crypto from the Mango Markets Exchange on Tuesday, and may get to keep almost half of it.\u003c/p\u003e\n\n\n\n\u003cfigure class=\"wp-block-image size-large\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"588\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/image-41-1024x588.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2327\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-41-1024x588.png 1024w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-41-300x172.png 300w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-41-768x441.png 768w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/image-41.png 1359w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"\u003e\u003c/figure\u003e\n\n\n\n\u003cp\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003eMango DAO has offered a deal to the thief who made off with\u0026nbsp;\u003ca href=\"https://decrypt.co/111727/solana-defi-trading-platform-mango-markets-loses-100m-in-hack\" target=\"_blank\" rel=\"noreferrer noopener\"\u003e$100 million\u003c/a\u003e\u0026nbsp;in crypto from an exploit in the Mango Markets platform earlier this week—a way to avoid a criminal investigation and pay off bad debt.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe Mango\u0026nbsp;\u003ca href=\"https://decrypt.co/?post_type=post\u0026amp;p=5728\"\u003eDAO\u003c/a\u003e, a decentralized autonomous organization that manages Mango Markets, has offered the hacker a bug bounty of $47 million, meaning that the thief would be required to send back $67 million worth of\u0026nbsp;\u003ca href=\"https://decrypt.co/?post_type=post\u0026amp;p=5720\"\u003etokens\u003c/a\u003e\u0026nbsp;under the terms of the deal.\u003c/p\u003e\n\n\n\n\u003cp\u003e“We are seeking to make users whole to the extent possible,” the\u0026nbsp;\u003ca href=\"https://dao.mango.markets/dao/MNGO/proposal/GYhczJdNZAhG24dkkymWE9SUZv8xC4g8s9U8VF5Yprne\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eMango DAO proposal says\u003c/a\u003e, addressing the thief.\u003c/p\u003e\n\n\n\n\u003cp\u003eOn Tuesday, a hacker was able to steal over $100 million through an exploit in the Mango Markets Solana\u0026nbsp;\u003ca href=\"https://decrypt.co/?post_type=post\u0026amp;p=25908\"\u003eDeFi\u003c/a\u003e\u0026nbsp;exchange. The attacker temporarily drove up the value of their collateral and then took out loans from the Mango treasury.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe DAO is a so-called Decentralized Autonomous Organization (“DAO”). DAOs run through rules encoded as smart contracts, which in turn are computer programs that facilitate, verify, or enforce the negotiation or performance of a contract, or that make a contractual clause unnecessary. In simple terms, think of any contract between two parties that gets translated into code, so it doesn’t need any external action but does automatically what was agreed. Smart Contracts are a pretty revolutionary and powerful concept by itself and if you want to know more about it, read our separate post on the subject.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe idea of a DAO somewhat is that once launched it can run based on its underlying smart contracts alone. The DAO’s smart contracts are based on Etherum, a public blockchain (which is a distributed database – for more information on blockchain, see\u0026nbsp;\u003ca href=\"https://planetcompliance.com/2016/03/22/the-basics-of-blockchain/\"\u003ehere\u003c/a\u003e) platform with programmable transaction functionality that is also the basis for ether (or ETH), a cryptocurrency. ETH is a cryptocurrency similar to Bitcoin, but very popular since it offers a wider range of services and therefore sometimes considered a considerable challenger of Bitcoin as the leading cryptocurrency.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe DAO is fuelled using ether, which creates DAO tokens. DAO token holders will have the right to vote on investment proposals (proportional to the number of tokens held) as well as the opportunity to receive rewards generated by the output of the work from the contractors’ proposals. Since it is decentralized autonomous organization that is represented only by its smart contracts, it has no physical address and people only interact as contractors or curators, but not in managerial roles in the traditional sense. However, it is supported by a limited company and a cryptocurrency exchange in Switzerland, both chosen with a view to the legal and regulatory framework. The DAO is intended as a form of venture capital vehicle that would invest in projects in the sharing economy. Prior to the attack, the fund’s value was around $150 million in ether.\u003c/p\u003e\n\n\n\n\u003cp\u003eSo while its creators hoped to build a more democratic financial institution that would be safe against the fallibility of humans by trusting the trustless concept of the blockchain and smart contracts, it seems human error is at the bottom of the heist.\u003c/p\u003e\n\n\n\n\u003cp\u003eThough it is not entirely certain yet how the money has been stolen, it appears that the hacker exploited a programing mistake in the code of the DAO. Weaknesses in the code had already been highlighted before and experts in the field had already called to fix critical problems. At this point it is important to recall that as a blockchain-enabled organization, the DAO is completely transparent and everything is done by the code, which anyone can see and audit. So, it seems that what happened – in a very simplified way – was that the hacker sent repeated transaction request to transfer funds to a DAO clone. Because of the programming error, the system possibly did not immediately update the balance, allowing the attacker to drain the account.\u003c/p\u003e\n\n\n\n\u003cp\u003eSince then the discussion has been how to respond to the attack. In an initial response, Vitalik Buterin, one of Ethereum’s founders, publicly asked online currency exchanges to suspend trading of ether and DAO tokens as well as deposits and withdrawals of the cryptocurrency.\u003c/p\u003e\n\n\n\n\u003cp\u003eBecause of a restriction in the code pay-outs are delayed for at least one week, possibly even longer, the hacker will not be able to access the funds and give The DAO community some time. Several options are currently discussed: The community could decide to do nothing, preserve the system and let the DAO token holders loose their investment. Or the so-called “hard-fork” where the Ethereum community could decide to roll back all transactions to a specific point in time before the attack. Or the network could be updated to ensure that all transactions from the hacker’s ether address are blocked, basically freezing the account and trying to exploit a similar programing error to “steel” the money back since the DAO clone is likely to contain the same code structure that made the original attack possible.\u003c/p\u003e\n\n\n\n\u003cp\u003eRegardless which course is decided on, what are the likely consequences for the DAO, Ethereum and the Blockchain in general after this incident?\u003cbr\u003eStephen Tual, COO of Slock.it, the company that had worked on the development of The DAO, stated that The DAO is definitely going to close. Whether that is the case is to be seen as in a leaderless organization no one person alone can decide on the fate of the organisation. The future of the investment vehicle is cast into serious doubt in any case by the theft itself, as it is questionable whether anyone would put money in a construction that has a proven vulnerability even when its makers promise to fix the issues. Trust, after all, is relevant even for a trustless concept when it comes to money.\u003c/p\u003e\n\n\n\n\u003cp\u003eThe more damaging aspect for the DAO, but also for Ethereum and potentially even the blockchain technology lies potentially in the actions to get the ether back. In comments across the web it has been compared with a bailout for banks that are too big to fail and that investors simply didn’t understand the risks of their investments. If the system is supposed to be flawless and save against tempering, isn’t meddling with it because of an, albeit very significant and expensive, programming error, undermining the whole idea? If people decide on whether transactions are to be reversed or not instead of the underlying smart contract, what is the worth of such an instrument if it’s only useful if anything goes according to plan?\u003c/p\u003e\n\n\n\n\u003cp\u003eRegardless what happens next it is an immensely important case as well from a legal and regulatory perspective: One tweet even hinted that a short bet on Ether was placed on one cryptocurrencies exchange shortly before the attack, which reminds us that traditional regulatory aspects like Market Abuse are more than relevant in the digital age. The tweet demanded an investigation though that raises the interesting questions about jurisdiction, governing legal frameworks and regulation, but that is only a side aspect to the story for now (though it would make sense from an economical perspective since the thief is unlikely to be able to access the Ether he stole and in that way could gain a monetary benefit from the heist).\u003c/p\u003e\n\n\n\n\u003cp\u003eIn an interesting post at\u0026nbsp;\u003ca href=\"http://www.coindesk.com/sue-dao-hacker/\"\u003eCoindesk\u003c/a\u003e, a US lawyer discussed the incident from a perspective of criminal law (Theft? Yes!), civil law (sue the hacker? Sure, seems everything can be sued) and tort law.\u003c/p\u003e\n\n\n\n\u003cp\u003eAnd even more interesting is the question whether the hacker only exploited a loophole in the code. In a message to the DAO and the Ethereum community, which is allegedly from the person responsible for the attack, the hacker described his action simply as using an intentional feature of the code and stated that any action to get the funds back, would amount to seizure of my legitimate and rightful ether, claimed legally through the terms of a smart contract, threatening trying to do so with legal action.\u003c/p\u003e\n\n\n\n\u003cp\u003eEverything is in flux: at the time of writing this, the DAO community is voting on whether to take action and, if so, in what form. Someone claiming to be an intermediary on behalf of the attackers has published a note, making it look like their holding the stolen ether ransom, and tweets on the subject get seemingly posted every second.\u003c/p\u003e\n\n\n\n\u003cp\u003eSo to summarise, plenty of open questions, an uncertain future for the DAO, but maybe there is a silver lining that comes from this. Maybe this is only a costly episode on a steep learning curve, similar to other forms of innovation, and maybe this will lead to more care, diligence and scrutiny in future blockchain projects, which in the end might not be so bad after all.\u003c/p\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003ch2 class=\"wp-block-heading\"\u003eLiterature:\u003c/h2\u003e\n\n\n\n\u003cul\u003e\n\u003cli\u003e\u003cem\u003e\u003ca href=\"https://cryptodeep.ru/doc/Understanding_a_Revolutionary_and_Flawed_Grand_Experiment_in_Blockchain__The_DAO_Attack_Journal_of_Cases_on_Information_Technology.pdf\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eUnderstanding a Revolutionary and Flawed Grand Experiment in Blockchain: The DAO Attack Journal of Cases on Information Technology\u003c/a\u003e\u003c/em\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003ch1 class=\"wp-block-heading\" id=\"22d1\"\u003eConclusion\u003c/h1\u003e\n\n\n\n\u003cp id=\"ad85\"\u003eI’ve learned a lot understanding the DAO exploit, mainly that programming smart contracts is not an easy task and it should be done rigorously. I still have lots of unsolved questions such as: Do we need fallback functions at all? Apparently this was fixed in the new version of Solidity. However, the problem is still present at the EVM level because a hacker can program in opcode and avoid the Solidity’s security \u003c/p\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://github.com/demining/Dao-Exploit\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eGitHub\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://t.me/cryptodeeptech\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eTelegram:\u0026nbsp;https://t.me/cryptodeeptech\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003ca href=\"https://youtu.be/-QDYiKCwOaA\" target=\"_blank\" rel=\"noreferrer noopener\"\u003e\u003cstrong\u003eVideo: https://youtu.be/-QDYiKCwOaA\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://cryptodeeptech.ru/dao-exploit\" target=\"_blank\" rel=\"noreferrer noopener\"\u003eSource: https://cryptodeeptech.ru/dao-exploit\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\n\n\n\u003chr class=\"wp-block-separator has-alpha-channel-opacity\"\u003e\n\n\n\u003cdiv class=\"wp-block-image\"\u003e\n\u003cfigure class=\"aligncenter size-large\"\u003e\u003cimg decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"576\" src=\"./Cryptanalysis of the DAO exploit - Multi-Stage Attack - CRYPTO DEEP TECH_files/044-1-1024x576.png\" alt=\"Cryptanalysis of the DAO exploit \u0026amp; Multi-Stage Attack\" class=\"wp-image-2343\" srcset=\"https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-1-1024x576.png 1024w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-1-300x169.png 300w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-1-768x432.png 768w, https://cryptodeeptech.ru/wp-content/uploads/2023/06/044-1.png 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\"\u003e\u003c/figure\u003e\u003c/div\u003e\n\n\n\u003cp\u003e\u003c/p\u003e\n\n\n\n\u003cp\u003e\u003c/p\u003e\n\t\u003c/div\u003e\u003c!-- .entry-content --\u003e\n\n\t\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdemining%2Fdao-exploit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdemining%2Fdao-exploit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdemining%2Fdao-exploit/lists"}