Update Mar 29 2017
The latest instructions can be found at The DAO Refunds.
Notes
- This Withdrawal contract only allows the conversion of The DAO tokens (DAO) into ethers (ETH) at the rate of 100 DAOs = 1 ETH.
- The way the Withdrawal contract has been coded means that you HAVE to approve the transfer of ALL DAOs in your account, as the Withdrawal contract will only transfer ALL of your DAOs in the one go. If you do not approve all of your DAOs to be transferred, the
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:
- Contract Name:
The DAO Withdrawal
- Contract Address:
0xbf4ed7b27f1d666546e30d74d50d173d20bca754
- JSON Interface:
[{"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
- Under the Wallet menu, select the account from which you want to convert DAOs into ETH.
- Double click on the account address and copy the address into your clipboard using Control-C in Linux or Windows, or Command-C on a MacBook.
Get the balance of the account from which you want to convert your DAOs into ETHs
- In the Contract menu, select The DAO contract.
- Scroll down to the Balance of function under the Read From Contract column on the left.
- Paste the address in your clipboard into the owner-address field.
- Double click on the Balance displayed and copy the balance into your clipboard using Control-C in Linux or Windows, or Command-C on a MacBook.
Approve the transfer of your account's DAO balance to the Withdrawal contract address
- In the Contract menu, select The DAO contract.
- Under the Write To Contract column on the right, select the Approve function.
- Paste the balance from your clipboard into the amount-256 bits unsigned integer field using Control-V in Linux or Windows, or Command-V on a MacBook.
- Enter the Withdrawal contract address
0xbf4ed7b27f1d666546e30d74d50d173d20bca754
in the spender-address field.
- Under the Execute from field, select the account from which you want to convert your DAOs into ETHs.
- Leave the Send ETHER field as 0.
- Click on Execute and enter your account password.
- You should get a transaction confirmation message.
Execute The Withdrawal Contract Function
Withdraw ETH from the Withdrawal contract
- In the Contract menu, select The DAO Withdrawal contract
- Under the Write To Contract column on the right, select the Withdraw function.
- Under the Execute from field, select the account from which you want to convert your DAOs into ETHs.
- Click on Execute and enter your account password.
- You should get a transaction confirmation message.
- Wait a short while and your ether balance should update. If not, restart Ethereum Wallet.
Withdrawal Method 3 - geth
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. For example:
geth --support-dao-fork console
The --support-dao-fork
setting is persisted between separate executions of geth
, so you only have to specify this parameter once.
Confirm your geth
version using
user@Kumquat:~$ geth version
Geth
Version: 1.4.10-stable
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.5.1
OS: linux
Here 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
works
geth --support-dao-fork --unlock {your account} console
...
Unlocking account {your account}
Passhrase: {enter your passphrase}
// Allow your blockchain to sync
> var account = "{your account}";
undefined
> var theDAOAddress = "0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413";
undefined
> var theDAOWithdrawalAddress = "0xbf4ed7b27f1d666546e30d74d50d173d20bca754";
undefined
> var theDAOABIFragment = [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"type":"function"}, {"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"}];
undefined
> var theDAO = web3.eth.contract(theDAOABIFragment).at(theDAOAddress);
undefined
> var approve = theDAO.approve(theDAOWithdrawalAddress, theDAO.balanceOf(account), {from: account});
undefined
> eth.getTransaction(approve);
// Repeat the command above until you see that blockNumber is not null
// Wait a few blocks (~ 15 seconds each) for your approve transaction to get mined
> var theDAOWithdrawalABIFragment = [{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"type":"function"}];
undefined
> var theDAOWithdrawal = web3.eth.contract(theDAOWithdrawalABIFragment).at(theDAOWithdrawalAddress);
undefined
> var withdrawal = theDAOWithdrawal.withdraw({from: account});
undefined
> eth.getTransaction(withdrawal);
// Repeat the command above until you see that blockNumber is not null
// Wait a few blocks (~15 second each) and check your new account balance
web3.fromWei(eth.getBalance(account), "ether")
11.023456789012345678
Withdrawal 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:
(Alternatively, you can download the Mist browser directly - see @johnmardlin
answer below).
Then:
- Make sure you've selected only the account which you used to purchase "The DAO" tokens.
- In Mist browse to https://slacknation.github.io/medium/12/12.html
- Click on "Approve", wait for one block
- Click on "Refund", wait for one block
![enter image description here](https://i.stack.imgur.com/MUyL9.png)
(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:
/// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
/// its behalf
/// @param _spender The address of the account able to transfer the tokens
/// @param _amount The amount of tokens to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _amount) returns (bool success);
Here is the Token.approve(...) function that implements the function defined above:
function approve(address _spender, uint256 _amount) returns (bool success) {
allowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}
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:
function withdraw(){
uint balance = mainDAO.balanceOf(msg.sender);
if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance))
throw;
}
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:
a) call dao.approve("0xbf4ed7b27f1d666546e30d74d50d173d20bca754", dao.balanceOf(youraccount))
b) call withdrawContract.withdraw()
Withdrawal Contract Source Code And Address
The source code for the Withdrawal contract can be found at 0xbf4ed7b27f1d666546e30d74d50d173d20bca754 and is as follows:
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(0xbb9bc244d798123fde783fcc1c72d3bb8c189413);
address public trustee = 0xda4a4626d3e16e094de3225a751aab7128e96526;
function withdraw(){
uint balance = mainDAO.balanceOf(msg.sender);
if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance))
throw;
}
function trusteeWithdraw() {
trustee.send((this.balance + mainDAO.balanceOf(this)) - mainDAO.totalSupply());
}
}
From The DAO's source code (referenced above), here is the Token.transferFrom(...)
function:
function transferFrom(
address _from,
address _to,
uint256 _amount
) noEther returns (bool success) {
if (balances[_from] >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0) {
balances[_to] += _amount;
balances[_from] -= _amount;
allowed[_from][msg.sender] -= _amount;
Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
}
Some Further References
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
Best Answer
I'm using the same unmodified script from How many ethers have been drained through the recursive call attacks on The DAO? to calculate the balance of The DAO and it's child DAOs.
For a finer categorisation of the different child DAOs, see the latest update from How do I get a refund for my The DAO tokens that was split into a child DAO?. There are several child DAOs with innocent splitters AND malicious drainers.
Here is the data generated from the ETC chain @ 05:58 02/08/2016 GMT:
NOTE that the baddies have drained 3641694.241898506992612606 ETH from child DAO #59
UPDATE 09:24 02/08/2016 GMT - What's happening within child DAO #59 on the ETC chain?
The balance from child DAO #59 has been moved by child DAO Proposal #10 into 0x10abb5efecdc09581f8b7cb95791fe2936790b4e that has an amount of 3642408.52761279270689932 ETC.
This is a grand child DAO that shares the same code as the original The DAO.
The same account has a balance on the ETH chain - 0x10abb5efecdc09581f8b7cb95791fe2936790b4e. Noticed by @DaxClassix on reddit.
From 2xC19LBZ on reddit:
From comparison, here is the data with child DAO #59 generated from the ETH pre hard-fork @ Jun 26 at 13:33 GMT, with the full data available in How many ethers have been drained through the recursive call attacks on The DAO?:
And here is the data generated from the ETH chain @ 06:05 02/08/2016 GMT: