Summary

The Issue - There seems to be some issue with certain wallets having rounding errors.

The Solution - The solution is to approve an amount larger than the balance in The DAO. The user with have to follow up with Jaxx if this issue is occurring within the Jaxx wallet functionality.

Alternatively, the user can perform the withdrawal using one of the 4 methods set out in How do I convert my The DAO tokens into ethers using the withdrawal contract after the hard fork?

Note that most of the failing DAO -> ETH transactions are due to there being a 0 DAO balance in The DAO. This could be because the user have already executed their DAO -> ETH refunds, or are performing the refunds on the wrong accounts.





Details

The WithdrawDAO contract relies on the user executing The DAO's approve(...) to allow the WithdrawDAO contract to transfer the tokens from the user's account to itself in return to refunding the equivalent amount to the user's account. Due to a rounding error somewhere in the process, an amount lower than the balance is being approved, and this causes an error in the withdrawal process.





Confirming The Rounding Error

I checked one of the failed withdrawals with there error message Warning! Error encountered during contract execution [Bad jump destination] as shown below:

I ran the following script in geth console and it confirmed that there was a shortfall of 341 wei in the amount approved for transfer and the balance.

var theDAOABIFragment = [{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"type":"function"}, {"type":"function","outputs":[{"type":"uint256","name":"balance"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner"}],"constant":true}]; undefined > var theDAOAddress = "0xbb9bc244d798123fde783fcc1c72d3bb8c189413" undefined > var theDAO = web3.eth.contract(theDAOABIFragment).at(theDAOAddress); undefined > var owner = "0x2de4452025f0f2c92f0cde55c0990e44abdc55b5".toLowerCase(); undefined > var spender = "0xbf4ed7b27f1d666546e30d74d50d173d20bca754".toLowerCase(); undefined > var amount = theDAO.allowance(owner, spender); undefined > var balance = theDAO.balanceOf(owner); undefined > var difference = amount.minus(balance); undefined > amount; 8333333333333332992 > balance; 8333333333333333333 > difference; -341 >

In the code below, you can see that WithdrawDAO.withdraw() calls TheDAO.transferFrom(...) with the full balance, but TheDAO.transferFrom(...) has the following checks:

balances[_from] >= _amount && allowed[_from][msg.sender] >= _amount

Which will not allow a withdrawal of the balance being more than the approved amount.

Here's another failing transaction:

> var owner = "0x1062eecd8d3ce44a469eddb82f309971dd02ec92".toLowerCase(); undefined > var amount = theDAO.allowance(owner, spender); undefined > var balance = theDAO.balanceOf(owner); undefined > var difference = amount.minus(balance); undefined > amount; 41338832000199999488 > balance; 41338832000200000000 > difference; -512

And another failing transaction:

> var owner = "0xe69619509a867775bf2c8b96408a82157fda695d".toLowerCase(); undefined undefined > var amount = theDAO.allowance(owner, spender); undefined > var balance = theDAO.balanceOf(owner); undefined > var difference = amount.minus(balance); undefined > amount; 2051130434782608640 > balance; 2051130434782608695 > difference; -55

And one more:

> var owner = "0x34657ab7e8a352e7c0a08c9a14a7f07a15ae98ce".toLowerCase(); undefined > var amount = theDAO.allowance(owner, spender); undefined > var balance = theDAO.balanceOf(owner); undefined > var difference = amount.minus(balance); undefined > amount; 20682758620689653760 > balance; 20682758620689655172 > difference; -1412

Some users have not approved the transfer before calling the withdraw:

> var owner = "0x98ba5387be9f93d777b52aef0d9c579851ee8142".toLowerCase(); > var amount = theDAO.allowance(owner, spender); undefined > var balance = theDAO.balanceOf(owner); undefined > var difference = amount.minus(balance); undefined > amount; 0 > balance; 39485714285714 > difference; -39485714285714 >

And some have zero balances to approve or transfer:

> var owner = "0x9c0af3a6f4a2266b3e2cf1cf81d30258e3862481".toLowerCase(); undefined > var amount = theDAO.allowance(owner, spender); undefined > var balance = theDAO.balanceOf(owner); undefined > var difference = amount.minus(balance); undefined > amount; 0 > balance; 0 > difference; 0 >





The WithdrawDAO Contract

Following is a fragment of the WithdrawDAO contract showing the withdraw() method:

contract WithdrawDAO { ... function withdraw(){ uint balance = mainDAO.balanceOf(msg.sender); if (!mainDAO.transferFrom(msg.sender, this, balance) || !msg.sender.send(balance)) throw; } ... }





The DAO Contract

Following are fragments from The DAO contact showing only the relevant classes and methods: