Update Mar 29 2017
The latest instructions can be found at The DAO Refunds.
At the hard-fork block #1,920,000 , the ETH balance from The DAO and it's child DAOs (which includes the balance from the extraBalance account) were transferred into the Withdrawal contract.
Immediately after the hard-fork, at block #1,920,090, the Withdrawal contact's trusteeWithdraw()
function was called in this transaction to transfer 463,798.08818109 ETH into TheDAOCurator multisig wallet.
See the ExtraBalance section in The DAO’s Edge Cases Multisig (Post Hard Fork) by Griff Green for the refund process being planned.
You should be able to find your account that contributed to the Extra Balance account in github.com/bokkypoobah/TheDAOData with further details in Which accounts contributed to The DAO's extraBalance account?:
Notes:
Update 08:07 Sep 13 2016 UTC
From ExtraBalance Withdraw Contract to be Funded on September 15th by Griff Green
, the Withdrawal contract will be funded by the curators on Sep 15 2016. You will then be able to withdraw your ethers using the methods listed below. You will find a more detailed guide to executing the Withdrawal contract using the Ethereum Wallet (similar to Method 2 below) in this linked article. Check that the ETH balance of 0x755cdba6AE4F479f7164792B318b2a06c759833B is non-zero before trying to execute your withdrawal.
Update 14:08 Sep 17 2016 UTC
The Withdrawal contract has been topped up by the curators with 344,917.580854976758120496 ETH. You can now execute your withdrawals!
Following are 3 methods to withdraw your funds:
- Method 1 - MyEtherWallet
- Method 2 - The Ethereum Wallet
- Method 3 -
geth
Method 1 - Withdrawing Using MyEtherWallet
Update 07:00 Sep 17 2016 UTC From @tayvano
:
Please make sure the funds have been depositted by checking that the extraBalance Withdraw Contract has a balance before attempting to withdraw. We have pushed this live as we are unavailable until the night of September 17th. Thank you.
Run MyEtherWallet from https://www.myetherwallet.com/#the-dao (Be careful as there are bogus MyEtherWallet phishing sites with similar URLs popping up over the internet aiming to steal your private keys.)
![enter image description here](https://i.stack.imgur.com/hmPg2.png)
Method 2 - Withdrawing Using The Ethereum Wallet
UPDATE 05:22 Sep 8 2016 UTC - The ExtraBalWithdrawal contract has been upgraded - replace your old version if you have already set it up. Also note that the Withdrawal contract has not been filled yet.
UPDATE 06:04 Sep 9 2016 UTC - @ledgerwatch has created the document How to withdraw from extraBalance refund contract that includes some steps for replay protection.
Make sure that you have downloaded Ethereum Wallet 0.8.1 or later.
The first time you start Ethereum Wallet 0.8.1, select "Yes" to the question "Do you want to activate the chain in which funds linked to the exploit are restored to a contract where they can be withdrawn by The DAO token holders?". You have now made the choice to use the hard-forked Ethereum chain.
Method 2 - Step 1 - Watch ExtraBalToken
Contract
In Ethereum Wallet, select the CONTRACTS page in the top menu. Click on WATCH CONTRACT.
- Enter a CONTRACT NAME of
ExtraBalToken
- Enter a CONTRACT ADDRESS of
0x5c40ef6f527f4fba68368774e6130ce6515123f2
- Enter in JSON INTERFACE field the following text:
[{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"seal","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"data","type":"uint256[]"}],"name":"fill","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"sealed","outputs":[{"name":"","type":"bool"}],"type":"function"},{"inputs":[],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]
- Click OK. Your Watch Contract should look like:
![enter image description here](https://i.stack.imgur.com/5C1XO.png)
Method 2 - Step 2 - Watch ExtraBalWithdrawal
Contract
In Ethereum Wallet, select the CONTRACTS page in the top menu. Click on WATCH CONTRACT.
- Enter a CONTRACT NAME of
ExtraBalWithdrawal
- Enter a CONTRACT ADDRESS of
0x755cdba6ae4f479f7164792b318b2a06c759833b
- Enter in JSON INTERFACE field the following text:
[{"constant":false,"inputs":[],"name":"clawback","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"mainDAO","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"trustee","outputs":[{"name":"","type":"address"}],"type":"function"}]
- Click OK. Your Watch Contract should look like:
![enter image description here](https://i.stack.imgur.com/q5uvQ.png)
Method 2 - Step 3 - Execute ExtraBalToken.Approve
This will approve the transfer of the tokens from your account to the ExtraBalWithdrawal
contract. Make sure that you send 0 ethers as this transaction may be replayed on the Ethereum Classic chain.
Select the CONTRACTS page in the top menu. Click on EXTRABALTOKEN.
- In the Balance of field on the left hand side of the page under READ FROM CONTACT, enter your account address, ALL IN LOWERCASE. Your withdrawal balance in wei should be displayed under your address.
- On the right hand side of the page under WRITE TO CONTRACT
- Select function Approve.
- In spender, enter
0x755cdba6ae4f479f7164792b318b2a06c759833b
, the address of the ExtraBalWithdrawal
contact.
- Copy the value in the Balance of result from the left hand side of the page and paste this figure into the value field.
- In Execute from, select your account.
- Enter 0 as the number of ETH under the Send ETHER field.
- Click on the EXECUTE button, enter your password and confirm.
Here is a screen image:
![enter image description here](https://i.stack.imgur.com/NZvW0.png)
Method 2 - Step 4 - Execute ExtraBalWithdrawal.Withdraw
--- DON'T EXECUTE THIS INSTRUCTION JUST YET. The curators have not filled the extraBalWithdrawal
contract and the execution will fail. This post will be updated when you are able to execute this script ---
This will withdraw ETH from the ExtraBalWithdrawal
contract to your account. Make sure that you send 0 ethers as this transaction may be replayed on the Ethereum Classic chain.
Select the CONTRACTS page in the top menu. Click on EXTRABALWITHDRAWAL. On the right hand side of the page under WRITE TO CONTRACT, Select function Withdraw. In Execute from, select your account. Enter 0 as the number of ETH under the Send ETHER field. Click on the EXECUTE button, enter your password and confirm. Here is a screen image:
![enter image description here](https://i.stack.imgur.com/uHyDS.png)
Method 3 - Withdrawing Using geth
UPDATE 05:22 Sep 8 2016 UTC - The ExtraBalWithdrawal contract has been upgraded and the code below has been tested. Note the new address and ABI in the geth
script below.
Make sure that you are running geth version 1.4.10 or later. And run your geth commands with the --support-dao-fork option
so that you are on the hard-forked blockchain.
--- DON'T EXECUTE THE FOLLOWING COMMANDS JUST YET. The curators have not filled the extraBalWithdrawal
contract and the execution will fail. This post will be updated when you are able to execute this script ---
user@Kumquat:~$ geth --support-dao-fork console
// Allow chain to sync
var account = "{your account}".toLowerCase();
personal.unlockAccount(account, "{your account password}")
var extraBalTokenAddress = "0x5c40ef6f527f4fba68368774e6130ce6515123f2";
var extraBalTokenABIFragment = [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"}, {"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"}];
var extraBalTokenContract = eth.contract(extraBalTokenABIFragment).at(extraBalTokenAddress);
var extraBalWithdrawalAddress = "0x755cdba6ae4f479f7164792b318b2a06c759833b";
var extraBalWithdrawalABIFragment = [{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"}];
var extraBalWithdrawalContract = eth.contract(extraBalWithdrawalABIFragment).at(extraBalWithdrawalAddress);
var balance = extraBalTokenContract.balanceOf(account);
console.log("Your extraBalTokenContract.balance() for " + account + " is " + web3.fromWei(balance, "ether") + " ethers");
// Approve the transfer of your tokens from the extraBalToken contract
// to the extraBalWithdrawal contract
var approve = extraBalTokenContract.approve(extraBalWithdrawalAddress, balance, {from: account, value: 0});
console.log("approve() returned " + approve);
// Wait for approve() to be mined. Repeat checking using the following command until you get a non-null result.
eth.getTransactionReceipt(approve).blockNumber;
var withdraw = extraBalWithdrawalContract.withdraw({from: account, value: 0});
console.log("withdraw() returned " + withdraw);
// Wait for withdraw() to be mined. Repeat checking using the following command until you get a non-null result.
eth.getTransactionReceipt(withdraw).blockNumber;
// Your withdrawal should now be complete. Check your account balance has received the withdrawal amount.
web3.fromWei(eth.getBalance(account), "ether");
ExtraBalToken Contract
@ledgerwatch in thedao.slack.com/messages/extrabal_community deployed the ExtraBalToken contract to 0x5c40ef6f527f4fba68368774e6130ce6515123f2.
contract ExtraBalToken {
uint256 public totalSupply;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
/* This generates a public event on the blockchain that will notify clients */
event Transfer(address indexed from, address indexed to, uint256 value);
/* Send coins */
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
balanceOf[msg.sender] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
}
/* Allow another contract to spend some tokens in your behalf */
function approve(address _spender, uint256 _value)
returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
/* A contract attempts to get the coins */
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
if (_value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
allowance[_from][msg.sender] -= _value;
Transfer(_from, _to, _value);
return true;
}
/* This unnamed function is called whenever someone tries to send ether to it */
function () {
throw; // Prevents accidental sending of ether
}
uint constant D160 = 0x10000000000000000000000000000000000000000;
address public owner;
function ExtraBalToken() {
owner = msg.sender;
}
bool public sealed;
// The 160 LSB is the address of the balance
// The 96 MSB is the balance of that address.
function fill(uint[] data) {
if ((msg.sender != owner)||(sealed))
throw;
for (uint i=0; i<data.length; i++) {
address a = address( data[i] & (D160-1) );
uint amount = data[i] / D160;
if (balanceOf[a] == 0) { // In case it's filled two times, it only increments once
balanceOf[a] = amount;
totalSupply += amount;
}
}
}
function seal() {
if ((msg.sender != owner)||(sealed))
throw;
sealed= true;
}
}
The contract ABI is: [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":false,"inputs":[],"name":"seal","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"data","type":"uint256[]"}],"name":"fill","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"sealed","outputs":[{"name":"","type":"bool"}],"type":"function"},{"inputs":[],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]
.
@ledgerwatch then fill(...)
ed the ExtraBalToken contract with the extraBalance values generated from a script similar to my getTheDAOCreatedTokenEventsWithNonZeroExtraBalance_v4 script. The results from my script can be found at CreatedTokenEventsWithNonZeroExtraBalance_v4.txt or CreatedTokenEventsWithNonZeroExtraBalance_v4.xlsx.
I have tested the ExtraBalToken contract - see the reconciliation script and report at github.com/bokkypoobah/TheDAOData/ExtraBalTokenValuesReconciliation.
The contract was then seal()
ed in block #2,202,674.
ExtraBalWithdrawal
Contract
UPDATE 05:22 Sep 8 2016 UTC
The ExtraBalWithdrawal
(WithdrawDAO
in the source code) has been upgraded and deployed to a new address. trusteeWithdraw(...)
has been replaced with clawback()
.
@ledgerwatch deployed the upgraded contract to 0x755cdba6ae4f479f7164792b318b2a06c759833b.
// Refund contract for extraBalance
// Amounts to be paid are tokenized in another contract and allow using the same refund contract as for theDAO
// Though it may be misleading, the names 'DAO', 'mainDAO' are kept here for the ease of code review
contract DAO {
function balanceOf(address addr) returns (uint);
function transferFrom(address from, address to, uint balance) returns (bool);
uint public totalSupply;
}
contract WithdrawDAO {
DAO constant public mainDAO = DAO(0x5c40ef6f527f4fba68368774e6130ce6515123f2);
address constant public trustee = 0xda4a4626d3e16e094de3225a751aab7128e96526;
function withdraw(){
uint balance = mainDAO.balanceOf(msg.sender);
if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance))
throw;
}
/**
* Return funds back to the curator.
*/
function clawback() external {
if (msg.sender != trustee) throw;
if (!trustee.send(this.balance)) throw;
}
}
The contract ABI is: [{"constant":false,"inputs":[],"name":"clawback","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"mainDAO","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"trustee","outputs":[{"name":"","type":"address"}],"type":"function"}]
.
NOTE This contract is yet to have the ethers added for The DAO token holders to withdraw.
Further References
Summary
At the hard-fork block #1,920,000 , the ETH balance from The DAO and it's child DAOs (which includes the balance from the extraBalance account) were transferred into the Withdrawal contract.
Immediately after the hard-fork, at block #1,920,090, the Withdrawal contact's trusteeWithdraw()
function was called in this transaction to transfer 463,798.08818109 ETH into TheDAOCurator multisig wallet.
The current TheDAOCurator wallet balance is 463,859.030790534 ETH ($5,802,876.48).
If you have executed a legitimate split from The DAO, your DAO balance has been moved to the child DAO and your DAO balance in The DAO is zeroed. As your DAO balance in The DAO is zero, you will not be able to convert your DAOs to ETHs using the procedures described in How do I convert my The DAO tokens into ethers using the withdrawal contract after the hard fork?.
A proposal for refunding the child DAO splitters can be found at github.com/dsystems-io/childDaoRefund. And the first refund has taken place for an initial test.
See also The DAO’s Edge Cases Multisig (Post Hard Fork).
UPDATE 15:03 Aug 11 2016 UTC
A few split DAO refunds have occurred - 0x422fbb5913e5c5a2cbd731246b62d9fbba0aadffb4f3e91540b76bbb528ee19b. 5.001 ETH refunded from TheDAOCurator to 0x0e0e733dd24168d85ecb5a62bb13385d31edf761.
For a sample contract see Refund for proposal #52.
UPDATE 01:06 Aug 21 2016 UTC
@ledgerwatch has been working hard in #child_dao_community@thedao.slack.com on progressing split DAO refunds and has the following message If You Were in the DAO and split, and your childDao was affected by hardFork:
If you were in splits from one of these proposals: 7, 10, 20, 23, 26, 28, 31, 37, 54, 57, 61, 65, 66 (pre-attack), please send me a private message here ASAP, quoting the proposal number. I will respond with instruction on how to receive your Ether back.
If you were in splits from proposals 35, 36, 53, 62, 67, 68, 70, 71, 73, 76, 87, please watch out for my next post in this subreddit, in the next couple of days I will post what the plan is for returning Ether.
If you were in 69, 74, 78, 81, 94 (child DAOs containing contributions from reentrant splits), please watch out for my posts too, the post about those will come a bit later on, most probably in few days.
Lots of info gets published on slack, but I appreciate that a lot of people don't go there, so I will in touch with you here.
UPDATE 06:28 Aug 23 2016 UTC
Second message from @ledgerwatch If You Were in the DAO and split, and your childDAO was affected by HardFork (2):
If you were in splits from one of these proposals: 20, 26, 31, 37, 57, 61 (pre-attack), please follow the instructions here to perform a self test: https://docs.google.com/document/d/1kD-K-TAz2be8rI737zc_-xpfKdnFlWrcQbHJop1Zwzs/edit?usp=sharing When done, send me a private message, quoting the proposal number, and Ether will be send to your refund contract shortly.
If you were in splits from proposals 35, 36, 53, 62, 67, 68, 70, 71, 73, 76, 87, please follow the instructions in this document to check how much you will get back (and let me know in a private or public message if something looks incorrect): https://docs.google.com/document/d/1qIudT496M--pmavVXaQC4cVgJQG0XkDY-3crglPDjrI/edit?usp=sharing The checking needs to be carried out within the next 14 days, after that time, if no issues found, the 'Mass-Refund' contract described in the document, will be loaded with Ether and available for withdraw. Therefore, provisional date for loading is 6th of September.
If you were in 69, 74, 78, 81, 94 (child DAOs containing contributions from reentrant splits), please watch out for my posts in this subreddit, the post about those will come a bit later on, most probably in few days.
Lots of info gets published on slack (channel #child_dao_community), but I appreciate that many people don't go there, so I will in touch with you here.
Please contact him on reddit or slack if you are involved in one of the splits listed above!
UPDATE 21:55 Sep 5 2016 UTC
From @ledgerwatch on The latest on the childDAO and extraBalance refunds:
Disclaimer: Information below is the current plan, to the best of my knowledge, but this plan can change, and there might be changes or delays.
PRE-ATTACK childDAOs: Only 4 non-refunded childDAOs left: 20, 31, 37, 57. The total amount to be refunded is 87 ETH. If you have tokens in any of these childDAO, please send me a private message quoting the number
POST-ATTACK childDAOs without reentrancies: 35, 36, 53, 62, 67, 68, 70, 71, 73, 76, 87. The refund is currently planned for tomorrow. The refund contract is here: http://etherscan.io/address/0x3da71558a40f63b960196cc0679847ff50fad22b In order to use it, you need call 'withdraw' function, passing the address of your childDAO as argument. You can look up the address of your childDAO in the source code. The new feature of etherscan, on the tab 'Read contract', allows you to quickly lookup how much you would get back. The total amount to be sent to this contract is around 21'395 ETH
POST-ATTACK childDAOs with reentrancies: 69, 74, 78. There are only 5 addresses that qualify for the refund, those are the addresses that did not use reentrancy in their split. The owners of the 2 of them have already cryptographically confirmed that they are OK for the refund to be sent directly to these addresses (they are confident that these addresses are not vulnerable to any possible replays). The remaining 3 addresses are:
0x5b5d8c8eed6c85ac215661de026676823faa0a0c
0xab9acc3c451e43e18dd61ab11048c07b74c99eee
0xe1e278e5e6bbe00b2a41d49b60853bf6791ab614
If you control any of these 3 account, send me a private message and I will ask you for a confirmation. Currently there is no set date for these refunds, but they will be initiated very soon after the previous round of refunds, so soon after 6th of September.
You may want to transfer your ETHs after you have withdrawn them. To prevent the replaying of your ETH transfer transaction on the non-hard-forked Ethereum Classic chain, see How to conditionally send ethers to another account post-hard-fork to protect yourself from replay attacks.
Details
Quoting GrifffGreeen in reddit.com/r/ethereum - Curator Multisig: extraBalance & childDAO tokens announcement Early next week dated 21 July 2016:
Expect an update detailing how the people that sent ether to the extraBalance and childDAO token holders will be able to claim their ether early next week.
For the extraBalance: It will likely be a smart contract that will allow any one who paid into the extraBalance to claim the ether they sent to it, with or without DAO tokens.
The childDAO token holders can also join the #child_dao_community in The DAO's Slack to stay up to date on the developments.
So if you have executed a legitimate split from The DAO, join the #child_dao_community at thedao.slack.com and contact @griff
to provide details of your split including:
- Split DAO's you joined (proposal numbers).
- Address of your childDAO
- Addresses that you used to split.
- How many DAO tokens each address burned.
- Best way to contact you :slightly_smiling_face:
- Any other relevant info that will help (did you send ETH as a proposal deposit? Is there one address you want all of the ETH to be sent to?)
Source: @griff
in #child_dao_community at thedao.slack.com
UPDATE 06:56 06 Aug 2016 GMT
Here's an updated DRAFT refund proposal for refunding the child DAO splitters from github.com/dsystems-io/childDaoRefund:
childDaoWithdraw
A set of contracts to withdraw ETH from the childDAOs which split innocently from the main DAO contract. Based on these contracts the estimated ETH owed to innocent splitters (those who called splitDAO()
without reentry) is 112,164.96789251 ETH
Resources
5 Classes of childDAOs
- Safe Children: Splits that were able to execute proposals to withdraw their ETH prior to the hardfork at block 1920000. We don't need to worry about these as their ETH was successfully withdrawn.
- Trusted Token Children: Splits that occurred prior to the first reentry attack and were never joined via a reentry attack. We can therefore trust that their tokens represent 1:100 ETH/cDAO.
- Untrusted Token Ratio Children: Splits with tokens that can't be trusted to represent 1:100 ETH/cDAO. They each called
split()
after the reentry attack and therefore have a ratio < 1:100 ETH/cDAO. They were however NOT joined via reentry attack.
- Untrusted Token Ratio With Reentry Children: Splits with tokens that don't represent 1:00 ETH/cDAO but were also joined via reentry attacks.
- Invalid Token Children: childDAO tokens created entirely via reentry attacks and therefore have no ETH value.
Class 1 - Safe Children
We can safely assume Class 1 DAOs are safe and are not in need of a solution. This includes the following Splits:
Class 2 - Trusted Token Children
Since these splits have a consistent ETH/cDAO token ratio, we can simply whitelist these DAOs and withdraw the token holder's ETH appropriately, similar to the main DAO withdrawal contract.
Based on this contract, the included childDAOs are owed: 69,704.90047138669 ETH
trustedChildWithdraw.sol
Uses a whiteList of trusted childDAOs to withdraw ETH by destroying tokens in each child. These addresses were compiled by running getNewDAOAddress()
on the original DAO for proposals 1-300 and examining the transactions for each childDAO. Only childDAOs unable to execute Proposals to withdraw ETH before the hardfork were included. All calls to splitDAO()
were credited 1 ETH for destroying 100 DAO tokens.
WhiteList includes:
Class 3 - Untrusted Token Ratio Children
As these tokens are not consistent in their ETH/cDAO ratio, we can determine each individual childDAO's rightful cDAO/ETH ratio based on how many DAO tokens they initially destroyed when calling splitDAO()
. These childDAOs were not joined via any reentry attacks so their tokens are valid except for the ratio of ETH they represent.
Based on this contract, the childDAOs included are owed 14,973.629251125047 ETH.
untrustedChildWithdraw.sol
Based upon trustedChildWithdraw.sol with the added complication that each childDAO has an individualized token multiplier. This multiplier was determined using the following formula ( (DAO / 100) / ETH )
. Where DAO
is the number of DAO tokens burned to create the split and ETH
represents the amount of ETH sent to the childDAO as a result of the split, calculated to 9 decimal places. All subsequent splits in a childDAO have the same multiplier.
List of splits that need an individualized calculation of ETH based on DAO tokens burned when calling splitDAO()
:
Class 4 - Untrusted Token Ratio With Reentry Children
These childDAOs also have a an untrusted token ratio, and were further joined via a reentry attack. Here we attempt to withdraw ETH from these splits individually based on the amount of DAO tokens they burned.
The total value of ETH owed to the splitters in this contract is 27,486.438169998 ETH.
infiltratedChildWithdraw.sol
This contract compiles the list of innocent (no-reentry) splitters from childDAOs that were joined via other reentry splitters (black and white hats). It then withdraws each innocent account when sufficient ETH is sent from the curator address. The contact accomplishes this as follows:
- Whitelists the 7 addresses which split innocently in reentry-attacked DAOs using an array.
- Builds a corresponding array that associates the amount (in Wei) that each address is owed from burning DAO tokens in the
splitDAO()
process. Here we calculate 100 DAO burned = 1 ETH owed.
- Uses a single function
withdraw()
that iterates over the whiteList and sends each address the appropriate amount of ETH.
- After successfully calling
withdraw()
the contract state isWithdrawn
is changed permanently to true
so as to prevent an accidently duplication.
- Restricts the call of
withdraw()
to only the Curator multisig address and only if the amount sent is sufficient to pay ALL recipients. Otherwise the entire transaction will fail with throw
. Failure of any single send()
will also throw
.
The following is a list of infiltrated childDAOs and corresponding innocent splitDAO()
transactions within each of them that were used to build the contract:
** NOTE: The values the transactions in Proposal 78 have been summed within the contract because they all belong to the same address. **
Class 5 - Invalid Token Children
The following children have been explicitly excluded because all split transactions were reentry attacks and therefore all tokens are invalid.
If you notice any errors with these lists, please bring it to my attention. Any other feedback much appreciated.
Contributors
Could not have been possible without the help and validation of everyone over at the #child_dao_community channel in The DAO Slack
Further References
Best Answer
Update Mar 29 2017
The latest instructions can be found at The DAO Refunds.
Notes
withdraw()
function will throw an error, consuming all the gas specified with the transaction.Anyone who bought DAOs in the last two weeks of The DAO crowdfunding phase paid more than 1 ETH per 100 DAOs. The amount in excess of 1 ETH per 100 DAOs was stored in The DAO's extraBalance account. The balance of the extraBalance account has now been transferred into the curator's multisig wallet.
There is a separate process for purchasers who paid more than 1 ETH per 100 DAOs to get refunded the extra amount paid (over the 1 ETH per 100 DAOs). This process is not covered in this answer, but rest assured that the developers are trying their best to fairly distribute the excess funds back to the original DAO buyers.
See How do I get a refund for the amount I paid in excess of 1 ether to 100 The DAO tokens which will be updated when further details are announced.
If you have executed a legitimate split from The DAO, your DAO balance has been moved to the child DAO and your DAO balance in The DAO is zeroed. As your DAO balance in The DAO is zero, you will not be able to convert your DAOs to ETHs using the procedure in this Q&A.
See How do I get a refund for my The DAO tokens that was split into a child DAO? as you will need to contact TheDAOCurator for them to arrange for your refund.
Wait for some time after the hard fork before attempting to convert your DAOs into ETHs. There is no deadline for the withdrawals. The safest thing to do is wait.
Update 06:33 Oct 26 2016 Some DAO -> ETH transactions are failing due to rounding errors. See Why Are My The DAO To ETH Refunds Failing?.
Withdrawal Method 1 - MyEtherWallet
Go to http://www.myetherwallet.com/#the-dao
Upload / Paste your Keystore file / Private Key to access your wallet.
Press big red button.
Confirm that you are sure you want to withdraw.
Wait a couple seconds and 2 transaction links will appear. Wait about 30 more seconds and check the balance of your account on Etherscan. You should have more ETH and 0 DAO. I (@tayvano) confirmed it worked @ 6:43AM PDT using the MyEtherWallet donation account: http://etherscan.io/address/0x7cb57b5a97eabe94205c07890be4c1ad31e486a8
Withdrawal Method 2 - Ethereum Wallet
The (circularly referenced) article How to use the Withdraw Contract with Mist by Griff Green provides a step-by-step screen printed guide similar to the instructions below.
Make sure that you have downloaded Ethereum Wallet 0.8.1 or later.
The first time you start Ethereum Wallet 0.8.1, select "Yes" to the question "Do you want to activate the chain in which funds linked to the exploit are restored to a contract where they can be withdrawn by The DAO token holders?". You have now made the choice to use the hard-forked Ethereum chain.
If Ethereum Wallet is freezing, see UPDATE 23 Jul 2016 in How to remove The DAO contract from Ethereum Wallet (Mist) watch list as it is freezing?.
If you have not already added a watch on The DAO contract, see The DAO - How to add and watch the DAO contract. This step will give you access to approve the transfer of DAOs to the Withdrawal contract.
If you cannot find the Approve function as required below, reload the JSON interface for The DAO contract using the steps immediately above. If you have trouble using the Ethereum Wallet with a freezing display, try removing The DAO contract from the Ethereum Wallet (How to remove The DAO contract from Ethereum Wallet (Mist) watch list as it is freezing?), then watch The DAO contract again.
Add a watch on The DAO Withdrawal contract. Use the same procedure as in the link directly above, but set:
The DAO Withdrawal
0xbf4ed7b27f1d666546e30d74d50d173d20bca754
[{"constant":false,"inputs":[],"name":"trusteeWithdraw","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"mainDAO","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"trustee","outputs":[{"name":"","type":"address"}],"type":"function"}]
23:47 20/07/2016 AEST - I have confirmed that the process below using the Ethereum Wallet works
Approve The Transfer Of Your DAOs To The Withdrawal Contract
Get the account address from which you want to convert your DAOs into ETHs
Get the balance of the account from which you want to convert your DAOs into ETHs
Approve the transfer of your account's DAO balance to the Withdrawal contract address
0xbf4ed7b27f1d666546e30d74d50d173d20bca754
in the spender-address field.Execute The Withdrawal Contract Function
Withdraw ETH from the Withdrawal contract
Withdrawal Method 3 -
geth
Make sure that you are running
geth
version 1.4.10 or later. And run yourgeth
commands with the--support-dao-fork
option so that you are on the hard-forked blockchain. For example:The
--support-dao-fork
setting is persisted between separate executions ofgeth
, so you only have to specify this parameter once.Confirm your
geth
version usingHere is the process using
geth
to convert your DAOs into ETHs for your account{x}
.00:14 21/07/2016 AEST - I have confirmed that the process below using
geth
worksWithdrawal Method 4 - Ethereum Wallet In Mist Browser Mode
Make sure that you have downloaded Ethereum Wallet 0.8.1 or later.
The first time you start Ethereum Wallet 0.8.1, select "Yes" to the question "Do you want to activate the chain in which funds linked to the exploit are restored to a contract where they can be withdrawn by The DAO token holders?". You have now made the choice to use the hard-forked Ethereum chain. Exit from Ethereum Wallet.
Now run the Ethereum Wallet in the Mist browser mode using the following command from the subdirectory you installed the software in:
In Linux & the MacBook
In Windows
(Alternatively, you can download the Mist browser directly - see
@johnmardlin
answer below).Then:
(Added Method 4 as requested by @slacknation in https://www.reddit.com/r/ethereum/comments/4tx13d/how_do_i_withdraw_dao_tokens_eth_after_hf_update/)
Withdrawal Process Explanation
There is a two step process to convert your DAOs into ETHs.
a) Approve The Transfer Of DAOs From The DAO To The Withdrawal Contract
The first step is to approve the transfer of DAOs from The DAO into the Withdrawal contract. This is done by calling The DAO's
approve(...)
function, listed below:From The DAO's source code, here is the TokenInterface.approve() function definition:
Here is the Token.approve(...) function that implements the function defined above:
Once you have called The DAO's approve(...) function, you have created an approval for the Withdrawal contract to transfer your DAOs into the Withdrawal contract.
b) Convert Your DAOs Into ETHs With The Withdrawal Contract
The second step is to call the Withdrawal contract's
withdraw()
function to transfer DAOs from The DAO into the Withdrawal contract, and for the Withdrawal contract to send your account the equivalent amount in ETH.Here is the source code for the
withdraw()
function:Source of information
User @lefteris in thedao.slack.com stated that The DAO Withdrawal contract can be found at 0xbf4ed7b27f1d666546e30d74d50d173d20bca754 and the process to convert DAOs into ETHs are the following:
Withdrawal Contract Source Code And Address
The source code for the Withdrawal contract can be found at 0xbf4ed7b27f1d666546e30d74d50d173d20bca754 and is as follows:
From The DAO's source code (referenced above), here is the
Token.transferFrom(...)
function:Some Further References