ETH Price: $3,765.41 (+0.42%)
Gas: 4 Gwei

Transaction Decoder

Block:
19439807 at Mar-15-2024 10:39:47 AM +UTC
Transaction Fee:
0.001778128746631215 ETH $6.70
Gas Used:
54,395 Gas / 32.689194717 Gwei

Emitted Events:

520 DAO.Transfer( _from=[Sender] 0x268019657d95fcf28c812e76aa3c8f3e80f9b196, _to=[Receiver] WithdrawDAO, _amount=82627901448988862 )

Account State Difference:

  Address   Before After State Difference Code
0x26801965...e80f9b196
0.004318276549452322 Eth
Nonce: 1
0.085168049251809969 Eth
Nonce: 2
0.080849772702357647
(beaverbuild)
8.416397837130977165 Eth8.416399468980977165 Eth0.00000163185
0xBB9bc244...b8C189413
0xBf4eD7b2...d20bca754
(WithdrawDAO)
83,324.422873534117187688 Eth83,324.340245632668198826 Eth0.082627901448988862

Execution Trace

WithdrawDAO.CALL( )
  • DAO.balanceOf( _owner=0x268019657D95fcF28c812E76aA3c8F3e80f9b196 ) => ( balance=82627901448988862 )
  • DAO.transferFrom( _from=0x268019657D95fcF28c812E76aA3c8F3e80f9b196, _to=0xBf4eD7b27F1d666546E30D74d50d173d20bca754, _value=82627901448988862 ) => ( success=True )
  • ETH 0.082627901448988862 0x268019657d95fcf28c812e76aa3c8f3e80f9b196.CALL( )
    File 1 of 2: WithdrawDAO
    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());
        }
    }

    File 2 of 2: DAO
    /*
    
    - Bytecode Verification performed was compared on second iteration -
    
    This file is part of the DAO.
    
    The DAO is free software: you can redistribute it and/or modify
    it under the terms of the GNU lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    The DAO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU lesser General Public License for more details.
    
    You should have received a copy of the GNU lesser General Public License
    along with the DAO.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    
    /*
    Basic, standardized Token contract with no "premine". Defines the functions to
    check token balances, send tokens, send tokens on behalf of a 3rd party and the
    corresponding approval process. Tokens need to be created by a derived
    contract (e.g. TokenCreation.sol).
    
    Thank you ConsenSys, this contract originated from:
    https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/Standard_Token.sol
    Which is itself based on the Ethereum standardized contract APIs:
    https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
    */
    
    /// @title Standard Token Contract.
    
    contract TokenInterface {
        mapping (address => uint256) balances;
        mapping (address => mapping (address => uint256)) allowed;
    
        /// Total amount of tokens
        uint256 public totalSupply;
    
        /// @param _owner The address from which the balance will be retrieved
        /// @return The balance
        function balanceOf(address _owner) constant returns (uint256 balance);
    
        /// @notice Send `_amount` tokens to `_to` from `msg.sender`
        /// @param _to The address of the recipient
        /// @param _amount The amount of tokens to be transferred
        /// @return Whether the transfer was successful or not
        function transfer(address _to, uint256 _amount) returns (bool success);
    
        /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
        /// is approved by `_from`
        /// @param _from The address of the origin of the transfer
        /// @param _to The address of the recipient
        /// @param _amount The amount of tokens to be transferred
        /// @return Whether the transfer was successful or not
        function transferFrom(address _from, address _to, uint256 _amount) returns (bool success);
    
        /// @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);
    
        /// @param _owner The address of the account owning tokens
        /// @param _spender The address of the account able to transfer the tokens
        /// @return Amount of remaining tokens of _owner that _spender is allowed
        /// to spend
        function allowance(
            address _owner,
            address _spender
        ) constant returns (uint256 remaining);
    
        event Transfer(address indexed _from, address indexed _to, uint256 _amount);
        event Approval(
            address indexed _owner,
            address indexed _spender,
            uint256 _amount
        );
    }
    
    
    contract Token is TokenInterface {
        // Protects users by preventing the execution of method calls that
        // inadvertently also transferred ether
        modifier noEther() {if (msg.value > 0) throw; _}
    
        function balanceOf(address _owner) constant returns (uint256 balance) {
            return balances[_owner];
        }
    
        function transfer(address _to, uint256 _amount) noEther returns (bool success) {
            if (balances[msg.sender] >= _amount && _amount > 0) {
                balances[msg.sender] -= _amount;
                balances[_to] += _amount;
                Transfer(msg.sender, _to, _amount);
                return true;
            } else {
               return false;
            }
        }
    
        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;
            }
        }
    
        function approve(address _spender, uint256 _amount) returns (bool success) {
            allowed[msg.sender][_spender] = _amount;
            Approval(msg.sender, _spender, _amount);
            return true;
        }
    
        function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
            return allowed[_owner][_spender];
        }
    }
    
    
    /*
    This file is part of the DAO.
    
    The DAO is free software: you can redistribute it and/or modify
    it under the terms of the GNU lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    The DAO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU lesser General Public License for more details.
    
    You should have received a copy of the GNU lesser General Public License
    along with the DAO.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    
    /*
    Basic account, used by the DAO contract to separately manage both the rewards 
    and the extraBalance accounts. 
    */
    
    contract ManagedAccountInterface {
        // The only address with permission to withdraw from this account
        address public owner;
        // If true, only the owner of the account can receive ether from it
        bool public payOwnerOnly;
        // The sum of ether (in wei) which has been sent to this contract
        uint public accumulatedInput;
    
        /// @notice Sends `_amount` of wei to _recipient
        /// @param _amount The amount of wei to send to `_recipient`
        /// @param _recipient The address to receive `_amount` of wei
        /// @return True if the send completed
        function payOut(address _recipient, uint _amount) returns (bool);
    
        event PayOut(address indexed _recipient, uint _amount);
    }
    
    
    contract ManagedAccount is ManagedAccountInterface{
    
        // The constructor sets the owner of the account
        function ManagedAccount(address _owner, bool _payOwnerOnly) {
            owner = _owner;
            payOwnerOnly = _payOwnerOnly;
        }
    
        // When the contract receives a transaction without data this is called. 
        // It counts the amount of ether it receives and stores it in 
        // accumulatedInput.
        function() {
            accumulatedInput += msg.value;
        }
    
        function payOut(address _recipient, uint _amount) returns (bool) {
            if (msg.sender != owner || msg.value > 0 || (payOwnerOnly && _recipient != owner))
                throw;
            if (_recipient.call.value(_amount)()) {
                PayOut(_recipient, _amount);
                return true;
            } else {
                return false;
            }
        }
    }
    /*
    This file is part of the DAO.
    
    The DAO is free software: you can redistribute it and/or modify
    it under the terms of the GNU lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    The DAO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU lesser General Public License for more details.
    
    You should have received a copy of the GNU lesser General Public License
    along with the DAO.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    
    /*
     * Token Creation contract, used by the DAO to create its tokens and initialize
     * its ether. Feel free to modify the divisor method to implement different
     * Token Creation parameters
    */
    
    
    contract TokenCreationInterface {
    
        // End of token creation, in Unix time
        uint public closingTime;
        // Minimum fueling goal of the token creation, denominated in tokens to
        // be created
        uint public minTokensToCreate;
        // True if the DAO reached its minimum fueling goal, false otherwise
        bool public isFueled;
        // For DAO splits - if privateCreation is 0, then it is a public token
        // creation, otherwise only the address stored in privateCreation is
        // allowed to create tokens
        address public privateCreation;
        // hold extra ether which has been sent after the DAO token
        // creation rate has increased
        ManagedAccount public extraBalance;
        // tracks the amount of wei given from each contributor (used for refund)
        mapping (address => uint256) weiGiven;
    
        /// @dev Constructor setting the minimum fueling goal and the
        /// end of the Token Creation
        /// @param _minTokensToCreate Minimum fueling goal in number of
        ///        Tokens to be created
        /// @param _closingTime Date (in Unix time) of the end of the Token Creation
        /// @param _privateCreation Zero means that the creation is public.  A
        /// non-zero address represents the only address that can create Tokens
        /// (the address can also create Tokens on behalf of other accounts)
        // This is the constructor: it can not be overloaded so it is commented out
        //  function TokenCreation(
            //  uint _minTokensTocreate,
            //  uint _closingTime,
            //  address _privateCreation
        //  );
    
        /// @notice Create Token with `_tokenHolder` as the initial owner of the Token
        /// @param _tokenHolder The address of the Tokens's recipient
        /// @return Whether the token creation was successful
        function createTokenProxy(address _tokenHolder) returns (bool success);
    
        /// @notice Refund `msg.sender` in the case the Token Creation did
        /// not reach its minimum fueling goal
        function refund();
    
        /// @return The divisor used to calculate the token creation rate during
        /// the creation phase
        function divisor() constant returns (uint divisor);
    
        event FuelingToDate(uint value);
        event CreatedToken(address indexed to, uint amount);
        event Refund(address indexed to, uint value);
    }
    
    
    contract TokenCreation is TokenCreationInterface, Token {
        function TokenCreation(
            uint _minTokensToCreate,
            uint _closingTime,
            address _privateCreation) {
    
            closingTime = _closingTime;
            minTokensToCreate = _minTokensToCreate;
            privateCreation = _privateCreation;
            extraBalance = new ManagedAccount(address(this), true);
        }
    
        function createTokenProxy(address _tokenHolder) returns (bool success) {
            if (now < closingTime && msg.value > 0
                && (privateCreation == 0 || privateCreation == msg.sender)) {
    
                uint token = (msg.value * 20) / divisor();
                extraBalance.call.value(msg.value - token)();
                balances[_tokenHolder] += token;
                totalSupply += token;
                weiGiven[_tokenHolder] += msg.value;
                CreatedToken(_tokenHolder, token);
                if (totalSupply >= minTokensToCreate && !isFueled) {
                    isFueled = true;
                    FuelingToDate(totalSupply);
                }
                return true;
            }
            throw;
        }
    
        function refund() noEther {
            if (now > closingTime && !isFueled) {
                // Get extraBalance - will only succeed when called for the first time
                if (extraBalance.balance >= extraBalance.accumulatedInput())
                    extraBalance.payOut(address(this), extraBalance.accumulatedInput());
    
                // Execute refund
                if (msg.sender.call.value(weiGiven[msg.sender])()) {
                    Refund(msg.sender, weiGiven[msg.sender]);
                    totalSupply -= balances[msg.sender];
                    balances[msg.sender] = 0;
                    weiGiven[msg.sender] = 0;
                }
            }
        }
    
        function divisor() constant returns (uint divisor) {
            // The number of (base unit) tokens per wei is calculated
            // as `msg.value` * 20 / `divisor`
            // The fueling period starts with a 1:1 ratio
            if (closingTime - 2 weeks > now) {
                return 20;
            // Followed by 10 days with a daily creation rate increase of 5%
            } else if (closingTime - 4 days > now) {
                return (20 + (now - (closingTime - 2 weeks)) / (1 days));
            // The last 4 days there is a constant creation rate ratio of 1:1.5
            } else {
                return 30;
            }
        }
    }
    /*
    This file is part of the DAO.
    
    The DAO is free software: you can redistribute it and/or modify
    it under the terms of the GNU lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    The DAO is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU lesser General Public License for more details.
    
    You should have received a copy of the GNU lesser General Public License
    along with the DAO.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    
    /*
    Standard smart contract for a Decentralized Autonomous Organization (DAO)
    to automate organizational governance and decision-making.
    */
    
    
    contract DAOInterface {
    
        // The amount of days for which people who try to participate in the
        // creation by calling the fallback function will still get their ether back
        uint constant creationGracePeriod = 40 days;
        // The minimum debate period that a generic proposal can have
        uint constant minProposalDebatePeriod = 2 weeks;
        // The minimum debate period that a split proposal can have
        uint constant minSplitDebatePeriod = 1 weeks;
        // Period of days inside which it's possible to execute a DAO split
        uint constant splitExecutionPeriod = 27 days;
        // Period of time after which the minimum Quorum is halved
        uint constant quorumHalvingPeriod = 25 weeks;
        // Period after which a proposal is closed
        // (used in the case `executeProposal` fails because it throws)
        uint constant executeProposalPeriod = 10 days;
        // Denotes the maximum proposal deposit that can be given. It is given as
        // a fraction of total Ether spent plus balance of the DAO
        uint constant maxDepositDivisor = 100;
    
        // Proposals to spend the DAO's ether or to choose a new Curator
        Proposal[] public proposals;
        // The quorum needed for each proposal is partially calculated by
        // totalSupply / minQuorumDivisor
        uint public minQuorumDivisor;
        // The unix time of the last time quorum was reached on a proposal
        uint  public lastTimeMinQuorumMet;
    
        // Address of the curator
        address public curator;
        // The whitelist: List of addresses the DAO is allowed to send ether to
        mapping (address => bool) public allowedRecipients;
    
        // Tracks the addresses that own Reward Tokens. Those addresses can only be
        // DAOs that have split from the original DAO. Conceptually, Reward Tokens
        // represent the proportion of the rewards that the DAO has the right to
        // receive. These Reward Tokens are generated when the DAO spends ether.
        mapping (address => uint) public rewardToken;
        // Total supply of rewardToken
        uint public totalRewardToken;
    
        // The account used to manage the rewards which are to be distributed to the
        // DAO Token Holders of this DAO
        ManagedAccount public rewardAccount;
    
        // The account used to manage the rewards which are to be distributed to
        // any DAO that holds Reward Tokens
        ManagedAccount public DAOrewardAccount;
    
        // Amount of rewards (in wei) already paid out to a certain DAO
        mapping (address => uint) public DAOpaidOut;
    
        // Amount of rewards (in wei) already paid out to a certain address
        mapping (address => uint) public paidOut;
        // Map of addresses blocked during a vote (not allowed to transfer DAO
        // tokens). The address points to the proposal ID.
        mapping (address => uint) public blocked;
    
        // The minimum deposit (in wei) required to submit any proposal that is not
        // requesting a new Curator (no deposit is required for splits)
        uint public proposalDeposit;
    
        // the accumulated sum of all current proposal deposits
        uint sumOfProposalDeposits;
    
        // Contract that is able to create a new DAO (with the same code as
        // this one), used for splits
        DAO_Creator public daoCreator;
    
        // A proposal with `newCurator == false` represents a transaction
        // to be issued by this DAO
        // A proposal with `newCurator == true` represents a DAO split
        struct Proposal {
            // The address where the `amount` will go to if the proposal is accepted
            // or if `newCurator` is true, the proposed Curator of
            // the new DAO).
            address recipient;
            // The amount to transfer to `recipient` if the proposal is accepted.
            uint amount;
            // A plain text description of the proposal
            string description;
            // A unix timestamp, denoting the end of the voting period
            uint votingDeadline;
            // True if the proposal's votes have yet to be counted, otherwise False
            bool open;
            // True if quorum has been reached, the votes have been counted, and
            // the majority said yes
            bool proposalPassed;
            // A hash to check validity of a proposal
            bytes32 proposalHash;
            // Deposit in wei the creator added when submitting their proposal. It
            // is taken from the msg.value of a newProposal call.
            uint proposalDeposit;
            // True if this proposal is to assign a new Curator
            bool newCurator;
            // Data needed for splitting the DAO
            SplitData[] splitData;
            // Number of Tokens in favor of the proposal
            uint yea;
            // Number of Tokens opposed to the proposal
            uint nay;
            // Simple mapping to check if a shareholder has voted for it
            mapping (address => bool) votedYes;
            // Simple mapping to check if a shareholder has voted against it
            mapping (address => bool) votedNo;
            // Address of the shareholder who created the proposal
            address creator;
        }
    
        // Used only in the case of a newCurator proposal.
        struct SplitData {
            // The balance of the current DAO minus the deposit at the time of split
            uint splitBalance;
            // The total amount of DAO Tokens in existence at the time of split.
            uint totalSupply;
            // Amount of Reward Tokens owned by the DAO at the time of split.
            uint rewardToken;
            // The new DAO contract created at the time of split.
            DAO newDAO;
        }
    
        // Used to restrict access to certain functions to only DAO Token Holders
        modifier onlyTokenholders {}
    
        /// @dev Constructor setting the Curator and the address
        /// for the contract able to create another DAO as well as the parameters
        /// for the DAO Token Creation
        /// @param _curator The Curator
        /// @param _daoCreator The contract able to (re)create this DAO
        /// @param _proposalDeposit The deposit to be paid for a regular proposal
        /// @param _minTokensToCreate Minimum required wei-equivalent tokens
        ///        to be created for a successful DAO Token Creation
        /// @param _closingTime Date (in Unix time) of the end of the DAO Token Creation
        /// @param _privateCreation If zero the DAO Token Creation is open to public, a
        /// non-zero address means that the DAO Token Creation is only for the address
        // This is the constructor: it can not be overloaded so it is commented out
        //  function DAO(
            //  address _curator,
            //  DAO_Creator _daoCreator,
            //  uint _proposalDeposit,
            //  uint _minTokensToCreate,
            //  uint _closingTime,
            //  address _privateCreation
        //  );
    
        /// @notice Create Token with `msg.sender` as the beneficiary
        /// @return Whether the token creation was successful
        function () returns (bool success);
    
    
        /// @dev This function is used to send ether back
        /// to the DAO, it can also be used to receive payments that should not be
        /// counted as rewards (donations, grants, etc.)
        /// @return Whether the DAO received the ether successfully
        function receiveEther() returns(bool);
    
        /// @notice `msg.sender` creates a proposal to send `_amount` Wei to
        /// `_recipient` with the transaction data `_transactionData`. If
        /// `_newCurator` is true, then this is a proposal that splits the
        /// DAO and sets `_recipient` as the new DAO's Curator.
        /// @param _recipient Address of the recipient of the proposed transaction
        /// @param _amount Amount of wei to be sent with the proposed transaction
        /// @param _description String describing the proposal
        /// @param _transactionData Data of the proposed transaction
        /// @param _debatingPeriod Time used for debating a proposal, at least 2
        /// weeks for a regular proposal, 10 days for new Curator proposal
        /// @param _newCurator Bool defining whether this proposal is about
        /// a new Curator or not
        /// @return The proposal ID. Needed for voting on the proposal
        function newProposal(
            address _recipient,
            uint _amount,
            string _description,
            bytes _transactionData,
            uint _debatingPeriod,
            bool _newCurator
        ) onlyTokenholders returns (uint _proposalID);
    
        /// @notice Check that the proposal with the ID `_proposalID` matches the
        /// transaction which sends `_amount` with data `_transactionData`
        /// to `_recipient`
        /// @param _proposalID The proposal ID
        /// @param _recipient The recipient of the proposed transaction
        /// @param _amount The amount of wei to be sent in the proposed transaction
        /// @param _transactionData The data of the proposed transaction
        /// @return Whether the proposal ID matches the transaction data or not
        function checkProposalCode(
            uint _proposalID,
            address _recipient,
            uint _amount,
            bytes _transactionData
        ) constant returns (bool _codeChecksOut);
    
        /// @notice Vote on proposal `_proposalID` with `_supportsProposal`
        /// @param _proposalID The proposal ID
        /// @param _supportsProposal Yes/No - support of the proposal
        /// @return The vote ID.
        function vote(
            uint _proposalID,
            bool _supportsProposal
        ) onlyTokenholders returns (uint _voteID);
    
        /// @notice Checks whether proposal `_proposalID` with transaction data
        /// `_transactionData` has been voted for or rejected, and executes the
        /// transaction in the case it has been voted for.
        /// @param _proposalID The proposal ID
        /// @param _transactionData The data of the proposed transaction
        /// @return Whether the proposed transaction has been executed or not
        function executeProposal(
            uint _proposalID,
            bytes _transactionData
        ) returns (bool _success);
    
        /// @notice ATTENTION! I confirm to move my remaining ether to a new DAO
        /// with `_newCurator` as the new Curator, as has been
        /// proposed in proposal `_proposalID`. This will burn my tokens. This can
        /// not be undone and will split the DAO into two DAO's, with two
        /// different underlying tokens.
        /// @param _proposalID The proposal ID
        /// @param _newCurator The new Curator of the new DAO
        /// @dev This function, when called for the first time for this proposal,
        /// will create a new DAO and send the sender's portion of the remaining
        /// ether and Reward Tokens to the new DAO. It will also burn the DAO Tokens
        /// of the sender.
        function splitDAO(
            uint _proposalID,
            address _newCurator
        ) returns (bool _success);
    
        /// @dev can only be called by the DAO itself through a proposal
        /// updates the contract of the DAO by sending all ether and rewardTokens
        /// to the new DAO. The new DAO needs to be approved by the Curator
        /// @param _newContract the address of the new contract
        function newContract(address _newContract);
    
    
        /// @notice Add a new possible recipient `_recipient` to the whitelist so
        /// that the DAO can send transactions to them (using proposals)
        /// @param _recipient New recipient address
        /// @dev Can only be called by the current Curator
        /// @return Whether successful or not
        function changeAllowedRecipients(address _recipient, bool _allowed) external returns (bool _success);
    
    
        /// @notice Change the minimum deposit required to submit a proposal
        /// @param _proposalDeposit The new proposal deposit
        /// @dev Can only be called by this DAO (through proposals with the
        /// recipient being this DAO itself)
        function changeProposalDeposit(uint _proposalDeposit) external;
    
        /// @notice Move rewards from the DAORewards managed account
        /// @param _toMembers If true rewards are moved to the actual reward account
        ///                   for the DAO. If not then it's moved to the DAO itself
        /// @return Whether the call was successful
        function retrieveDAOReward(bool _toMembers) external returns (bool _success);
    
        /// @notice Get my portion of the reward that was sent to `rewardAccount`
        /// @return Whether the call was successful
        function getMyReward() returns(bool _success);
    
        /// @notice Withdraw `_account`'s portion of the reward from `rewardAccount`
        /// to `_account`'s balance
        /// @return Whether the call was successful
        function withdrawRewardFor(address _account) internal returns (bool _success);
    
        /// @notice Send `_amount` tokens to `_to` from `msg.sender`. Prior to this
        /// getMyReward() is called.
        /// @param _to The address of the recipient
        /// @param _amount The amount of tokens to be transfered
        /// @return Whether the transfer was successful or not
        function transferWithoutReward(address _to, uint256 _amount) returns (bool success);
    
        /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
        /// is approved by `_from`. Prior to this getMyReward() is called.
        /// @param _from The address of the sender
        /// @param _to The address of the recipient
        /// @param _amount The amount of tokens to be transfered
        /// @return Whether the transfer was successful or not
        function transferFromWithoutReward(
            address _from,
            address _to,
            uint256 _amount
        ) returns (bool success);
    
        /// @notice Doubles the 'minQuorumDivisor' in the case quorum has not been
        /// achieved in 52 weeks
        /// @return Whether the change was successful or not
        function halveMinQuorum() returns (bool _success);
    
        /// @return total number of proposals ever created
        function numberOfProposals() constant returns (uint _numberOfProposals);
    
        /// @param _proposalID Id of the new curator proposal
        /// @return Address of the new DAO
        function getNewDAOAddress(uint _proposalID) constant returns (address _newDAO);
    
        /// @param _account The address of the account which is checked.
        /// @return Whether the account is blocked (not allowed to transfer tokens) or not.
        function isBlocked(address _account) internal returns (bool);
    
        /// @notice If the caller is blocked by a proposal whose voting deadline
        /// has exprired then unblock him.
        /// @return Whether the account is blocked (not allowed to transfer tokens) or not.
        function unblockMe() returns (bool);
    
        event ProposalAdded(
            uint indexed proposalID,
            address recipient,
            uint amount,
            bool newCurator,
            string description
        );
        event Voted(uint indexed proposalID, bool position, address indexed voter);
        event ProposalTallied(uint indexed proposalID, bool result, uint quorum);
        event NewCurator(address indexed _newCurator);
        event AllowedRecipientChanged(address indexed _recipient, bool _allowed);
    }
    
    // The DAO contract itself
    contract DAO is DAOInterface, Token, TokenCreation {
    
        // Modifier that allows only shareholders to vote and create new proposals
        modifier onlyTokenholders {
            if (balanceOf(msg.sender) == 0) throw;
                _
        }
    
        function DAO(
            address _curator,
            DAO_Creator _daoCreator,
            uint _proposalDeposit,
            uint _minTokensToCreate,
            uint _closingTime,
            address _privateCreation
        ) TokenCreation(_minTokensToCreate, _closingTime, _privateCreation) {
    
            curator = _curator;
            daoCreator = _daoCreator;
            proposalDeposit = _proposalDeposit;
            rewardAccount = new ManagedAccount(address(this), false);
            DAOrewardAccount = new ManagedAccount(address(this), false);
            if (address(rewardAccount) == 0)
                throw;
            if (address(DAOrewardAccount) == 0)
                throw;
            lastTimeMinQuorumMet = now;
            minQuorumDivisor = 5; // sets the minimal quorum to 20%
            proposals.length = 1; // avoids a proposal with ID 0 because it is used
    
            allowedRecipients[address(this)] = true;
            allowedRecipients[curator] = true;
        }
    
        function () returns (bool success) {
            if (now < closingTime + creationGracePeriod && msg.sender != address(extraBalance))
                return createTokenProxy(msg.sender);
            else
                return receiveEther();
        }
    
    
        function receiveEther() returns (bool) {
            return true;
        }
    
    
        function newProposal(
            address _recipient,
            uint _amount,
            string _description,
            bytes _transactionData,
            uint _debatingPeriod,
            bool _newCurator
        ) onlyTokenholders returns (uint _proposalID) {
    
            // Sanity check
            if (_newCurator && (
                _amount != 0
                || _transactionData.length != 0
                || _recipient == curator
                || msg.value > 0
                || _debatingPeriod < minSplitDebatePeriod)) {
                throw;
            } else if (
                !_newCurator
                && (!isRecipientAllowed(_recipient) || (_debatingPeriod <  minProposalDebatePeriod))
            ) {
                throw;
            }
    
            if (_debatingPeriod > 8 weeks)
                throw;
    
            if (!isFueled
                || now < closingTime
                || (msg.value < proposalDeposit && !_newCurator)) {
    
                throw;
            }
    
            if (now + _debatingPeriod < now) // prevents overflow
                throw;
    
            // to prevent a 51% attacker to convert the ether into deposit
            if (msg.sender == address(this))
                throw;
    
            _proposalID = proposals.length++;
            Proposal p = proposals[_proposalID];
            p.recipient = _recipient;
            p.amount = _amount;
            p.description = _description;
            p.proposalHash = sha3(_recipient, _amount, _transactionData);
            p.votingDeadline = now + _debatingPeriod;
            p.open = true;
            //p.proposalPassed = False; // that's default
            p.newCurator = _newCurator;
            if (_newCurator)
                p.splitData.length++;
            p.creator = msg.sender;
            p.proposalDeposit = msg.value;
    
            sumOfProposalDeposits += msg.value;
    
            ProposalAdded(
                _proposalID,
                _recipient,
                _amount,
                _newCurator,
                _description
            );
        }
    
    
        function checkProposalCode(
            uint _proposalID,
            address _recipient,
            uint _amount,
            bytes _transactionData
        ) noEther constant returns (bool _codeChecksOut) {
            Proposal p = proposals[_proposalID];
            return p.proposalHash == sha3(_recipient, _amount, _transactionData);
        }
    
    
        function vote(
            uint _proposalID,
            bool _supportsProposal
        ) onlyTokenholders noEther returns (uint _voteID) {
    
            Proposal p = proposals[_proposalID];
            if (p.votedYes[msg.sender]
                || p.votedNo[msg.sender]
                || now >= p.votingDeadline) {
    
                throw;
            }
    
            if (_supportsProposal) {
                p.yea += balances[msg.sender];
                p.votedYes[msg.sender] = true;
            } else {
                p.nay += balances[msg.sender];
                p.votedNo[msg.sender] = true;
            }
    
            if (blocked[msg.sender] == 0) {
                blocked[msg.sender] = _proposalID;
            } else if (p.votingDeadline > proposals[blocked[msg.sender]].votingDeadline) {
                // this proposal's voting deadline is further into the future than
                // the proposal that blocks the sender so make it the blocker
                blocked[msg.sender] = _proposalID;
            }
    
            Voted(_proposalID, _supportsProposal, msg.sender);
        }
    
    
        function executeProposal(
            uint _proposalID,
            bytes _transactionData
        ) noEther returns (bool _success) {
    
            Proposal p = proposals[_proposalID];
    
            uint waitPeriod = p.newCurator
                ? splitExecutionPeriod
                : executeProposalPeriod;
            // If we are over deadline and waiting period, assert proposal is closed
            if (p.open && now > p.votingDeadline + waitPeriod) {
                closeProposal(_proposalID);
                return;
            }
    
            // Check if the proposal can be executed
            if (now < p.votingDeadline  // has the voting deadline arrived?
                // Have the votes been counted?
                || !p.open
                // Does the transaction code match the proposal?
                || p.proposalHash != sha3(p.recipient, p.amount, _transactionData)) {
    
                throw;
            }
    
            // If the curator removed the recipient from the whitelist, close the proposal
            // in order to free the deposit and allow unblocking of voters
            if (!isRecipientAllowed(p.recipient)) {
                closeProposal(_proposalID);
                p.creator.send(p.proposalDeposit);
                return;
            }
    
            bool proposalCheck = true;
    
            if (p.amount > actualBalance())
                proposalCheck = false;
    
            uint quorum = p.yea + p.nay;
    
            // require 53% for calling newContract()
            if (_transactionData.length >= 4 && _transactionData[0] == 0x68
                && _transactionData[1] == 0x37 && _transactionData[2] == 0xff
                && _transactionData[3] == 0x1e
                && quorum < minQuorum(actualBalance() + rewardToken[address(this)])) {
    
                    proposalCheck = false;
            }
    
            if (quorum >= minQuorum(p.amount)) {
                if (!p.creator.send(p.proposalDeposit))
                    throw;
    
                lastTimeMinQuorumMet = now;
                // set the minQuorum to 20% again, in the case it has been reached
                if (quorum > totalSupply / 5)
                    minQuorumDivisor = 5;
            }
    
            // Execute result
            if (quorum >= minQuorum(p.amount) && p.yea > p.nay && proposalCheck) {
                if (!p.recipient.call.value(p.amount)(_transactionData))
                    throw;
    
                p.proposalPassed = true;
                _success = true;
    
                // only create reward tokens when ether is not sent to the DAO itself and
                // related addresses. Proxy addresses should be forbidden by the curator.
                if (p.recipient != address(this) && p.recipient != address(rewardAccount)
                    && p.recipient != address(DAOrewardAccount)
                    && p.recipient != address(extraBalance)
                    && p.recipient != address(curator)) {
    
                    rewardToken[address(this)] += p.amount;
                    totalRewardToken += p.amount;
                }
            }
    
            closeProposal(_proposalID);
    
            // Initiate event
            ProposalTallied(_proposalID, _success, quorum);
        }
    
    
        function closeProposal(uint _proposalID) internal {
            Proposal p = proposals[_proposalID];
            if (p.open)
                sumOfProposalDeposits -= p.proposalDeposit;
            p.open = false;
        }
    
        function splitDAO(
            uint _proposalID,
            address _newCurator
        ) noEther onlyTokenholders returns (bool _success) {
    
            Proposal p = proposals[_proposalID];
    
            // Sanity check
    
            if (now < p.votingDeadline  // has the voting deadline arrived?
                //The request for a split expires XX days after the voting deadline
                || now > p.votingDeadline + splitExecutionPeriod
                // Does the new Curator address match?
                || p.recipient != _newCurator
                // Is it a new curator proposal?
                || !p.newCurator
                // Have you voted for this split?
                || !p.votedYes[msg.sender]
                // Did you already vote on another proposal?
                || (blocked[msg.sender] != _proposalID && blocked[msg.sender] != 0) )  {
    
                throw;
            }
    
            // If the new DAO doesn't exist yet, create the new DAO and store the
            // current split data
            if (address(p.splitData[0].newDAO) == 0) {
                p.splitData[0].newDAO = createNewDAO(_newCurator);
                // Call depth limit reached, etc.
                if (address(p.splitData[0].newDAO) == 0)
                    throw;
                // should never happen
                if (this.balance < sumOfProposalDeposits)
                    throw;
                p.splitData[0].splitBalance = actualBalance();
                p.splitData[0].rewardToken = rewardToken[address(this)];
                p.splitData[0].totalSupply = totalSupply;
                p.proposalPassed = true;
            }
    
            // Move ether and assign new Tokens
            uint fundsToBeMoved =
                (balances[msg.sender] * p.splitData[0].splitBalance) /
                p.splitData[0].totalSupply;
            if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false)
                throw;
    
    
            // Assign reward rights to new DAO
            uint rewardTokenToBeMoved =
                (balances[msg.sender] * p.splitData[0].rewardToken) /
                p.splitData[0].totalSupply;
    
            uint paidOutToBeMoved = DAOpaidOut[address(this)] * rewardTokenToBeMoved /
                rewardToken[address(this)];
    
            rewardToken[address(p.splitData[0].newDAO)] += rewardTokenToBeMoved;
            if (rewardToken[address(this)] < rewardTokenToBeMoved)
                throw;
            rewardToken[address(this)] -= rewardTokenToBeMoved;
    
            DAOpaidOut[address(p.splitData[0].newDAO)] += paidOutToBeMoved;
            if (DAOpaidOut[address(this)] < paidOutToBeMoved)
                throw;
            DAOpaidOut[address(this)] -= paidOutToBeMoved;
    
            // Burn DAO Tokens
            Transfer(msg.sender, 0, balances[msg.sender]);
            withdrawRewardFor(msg.sender); // be nice, and get his rewards
            totalSupply -= balances[msg.sender];
            balances[msg.sender] = 0;
            paidOut[msg.sender] = 0;
            return true;
        }
    
        function newContract(address _newContract){
            if (msg.sender != address(this) || !allowedRecipients[_newContract]) return;
            // move all ether
            if (!_newContract.call.value(address(this).balance)()) {
                throw;
            }
    
            //move all reward tokens
            rewardToken[_newContract] += rewardToken[address(this)];
            rewardToken[address(this)] = 0;
            DAOpaidOut[_newContract] += DAOpaidOut[address(this)];
            DAOpaidOut[address(this)] = 0;
        }
    
    
        function retrieveDAOReward(bool _toMembers) external noEther returns (bool _success) {
            DAO dao = DAO(msg.sender);
    
            if ((rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /
                totalRewardToken < DAOpaidOut[msg.sender])
                throw;
    
            uint reward =
                (rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) /
                totalRewardToken - DAOpaidOut[msg.sender];
            if(_toMembers) {
                if (!DAOrewardAccount.payOut(dao.rewardAccount(), reward))
                    throw;
                }
            else {
                if (!DAOrewardAccount.payOut(dao, reward))
                    throw;
            }
            DAOpaidOut[msg.sender] += reward;
            return true;
        }
    
        function getMyReward() noEther returns (bool _success) {
            return withdrawRewardFor(msg.sender);
        }
    
    
        function withdrawRewardFor(address _account) noEther internal returns (bool _success) {
            if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply < paidOut[_account])
                throw;
    
            uint reward =
                (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account];
            if (!rewardAccount.payOut(_account, reward))
                throw;
            paidOut[_account] += reward;
            return true;
        }
    
    
        function transfer(address _to, uint256 _value) returns (bool success) {
            if (isFueled
                && now > closingTime
                && !isBlocked(msg.sender)
                && transferPaidOut(msg.sender, _to, _value)
                && super.transfer(_to, _value)) {
    
                return true;
            } else {
                throw;
            }
        }
    
    
        function transferWithoutReward(address _to, uint256 _value) returns (bool success) {
            if (!getMyReward())
                throw;
            return transfer(_to, _value);
        }
    
    
        function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
            if (isFueled
                && now > closingTime
                && !isBlocked(_from)
                && transferPaidOut(_from, _to, _value)
                && super.transferFrom(_from, _to, _value)) {
    
                return true;
            } else {
                throw;
            }
        }
    
    
        function transferFromWithoutReward(
            address _from,
            address _to,
            uint256 _value
        ) returns (bool success) {
    
            if (!withdrawRewardFor(_from))
                throw;
            return transferFrom(_from, _to, _value);
        }
    
    
        function transferPaidOut(
            address _from,
            address _to,
            uint256 _value
        ) internal returns (bool success) {
    
            uint transferPaidOut = paidOut[_from] * _value / balanceOf(_from);
            if (transferPaidOut > paidOut[_from])
                throw;
            paidOut[_from] -= transferPaidOut;
            paidOut[_to] += transferPaidOut;
            return true;
        }
    
    
        function changeProposalDeposit(uint _proposalDeposit) noEther external {
            if (msg.sender != address(this) || _proposalDeposit > (actualBalance() + rewardToken[address(this)])
                / maxDepositDivisor) {
    
                throw;
            }
            proposalDeposit = _proposalDeposit;
        }
    
    
        function changeAllowedRecipients(address _recipient, bool _allowed) noEther external returns (bool _success) {
            if (msg.sender != curator)
                throw;
            allowedRecipients[_recipient] = _allowed;
            AllowedRecipientChanged(_recipient, _allowed);
            return true;
        }
    
    
        function isRecipientAllowed(address _recipient) internal returns (bool _isAllowed) {
            if (allowedRecipients[_recipient]
                || (_recipient == address(extraBalance)
                    // only allowed when at least the amount held in the
                    // extraBalance account has been spent from the DAO
                    && totalRewardToken > extraBalance.accumulatedInput()))
                return true;
            else
                return false;
        }
    
        function actualBalance() constant returns (uint _actualBalance) {
            return this.balance - sumOfProposalDeposits;
        }
    
    
        function minQuorum(uint _value) internal constant returns (uint _minQuorum) {
            // minimum of 20% and maximum of 53.33%
            return totalSupply / minQuorumDivisor +
                (_value * totalSupply) / (3 * (actualBalance() + rewardToken[address(this)]));
        }
    
    
        function halveMinQuorum() returns (bool _success) {
            // this can only be called after `quorumHalvingPeriod` has passed or at anytime
            // by the curator with a delay of at least `minProposalDebatePeriod` between the calls
            if ((lastTimeMinQuorumMet < (now - quorumHalvingPeriod) || msg.sender == curator)
                && lastTimeMinQuorumMet < (now - minProposalDebatePeriod)) {
                lastTimeMinQuorumMet = now;
                minQuorumDivisor *= 2;
                return true;
            } else {
                return false;
            }
        }
    
        function createNewDAO(address _newCurator) internal returns (DAO _newDAO) {
            NewCurator(_newCurator);
            return daoCreator.createDAO(_newCurator, 0, 0, now + splitExecutionPeriod);
        }
    
        function numberOfProposals() constant returns (uint _numberOfProposals) {
            // Don't count index 0. It's used by isBlocked() and exists from start
            return proposals.length - 1;
        }
    
        function getNewDAOAddress(uint _proposalID) constant returns (address _newDAO) {
            return proposals[_proposalID].splitData[0].newDAO;
        }
    
        function isBlocked(address _account) internal returns (bool) {
            if (blocked[_account] == 0)
                return false;
            Proposal p = proposals[blocked[_account]];
            if (now > p.votingDeadline) {
                blocked[_account] = 0;
                return false;
            } else {
                return true;
            }
        }
    
        function unblockMe() returns (bool) {
            return isBlocked(msg.sender);
        }
    }
    
    contract DAO_Creator {
        function createDAO(
            address _curator,
            uint _proposalDeposit,
            uint _minTokensToCreate,
            uint _closingTime
        ) returns (DAO _newDAO) {
    
            return new DAO(
                _curator,
                DAO_Creator(this),
                _proposalDeposit,
                _minTokensToCreate,
                _closingTime,
                msg.sender
            );
        }
    }