Back to Home

Doge-ETH Bounty DAO

DAO
0xdbf03b407c01...3f8dddc8c6fb
FrontierContract #5,696Exact Bytecode MatchEdit this contract
Deployed December 28, 2015 (10 years ago)Block 762,866

The Doge-Ethereum Bounty DAO created by avsa on Dec 28, 2015. Funded over 5,400 ETH in bridge development, holds 50,000 MistCoin. Active 2015-2021.

Key Facts

Deployment Block
762,866
Deployment Date
Dec 28, 2015, 09:18 PM
Code Size
5.2 KB
Gas at Deploy
1,381,250
Transactions by Year
201519
201655
20179
201830
20201
20218
20231

Description

The Doge-Ethereum Bounty DAO, created by Alex Van de Sande (@avsa) on December 28, 2015. A governance contract with 8 members including Vitalik Buterin, Piper Merriam, Hudson Jameson, J. Ross Nicoll (Dogecoin developer), George Hallam, Max (Dogecoin), and Ming Chan, each with voting rights on proposals. Requires at least 5 votes and 3 approvals to pass. The DAO funded development of the Dogecoin-Ethereum bridge over several years, disbursing ETH to teams including Trubit and CoinFabrik for successfully sending Doge to the Ethereum Rinkeby testnet. It also holds 50,000 MistCoin ($WMC), the token Fabian Vogelsteller deployed on November 3, 2015 to prototype what became the ERC-20 standard. MistCoin predates ERC-20 by 16 days and does not implement the full standard, but it is the token that directly inspired it. The underlying contract is the ethereum.org Blockchain Congress tutorial source code compiled with Solidity 0.1.6.

Source Verified

SolidityExact bytecode match(5,357 bytes)
Compiler: d41f8b7

soljson v0.1.6+commit.d41f8b7c, optimizer ON. Creation TX (5357 bytes) = compiled (5229 bytes) + 128 bytes ABI-encoded constructor args (minimumQuorum=0, debatingPeriod=10000min, majorityMargin=0, congressLeader=0x0).

Heuristic Analysis

The following characteristics were detected through bytecode analysis and may not be accurate.

Detected Type: DAO

Frontier Era

The initial release of Ethereum. A bare-bones implementation for technical users.

Block span: 01,149,999
July 30, 2015March 14, 2016

Bytecode Overview

Opcodes5,357
Unique Opcodes217
Jump Instructions223
Storage Operations180

Verified Source Available

Source verified through compiler archaeology and exact bytecode matching.

View Verification Proof
Show source code (Solidity)
contract owned {
    address public owner;

    function owned() {
        owner = msg.sender;
    }

    modifier onlyOwner {
        if (msg.sender != owner) throw;
        _
    }

    function transferOwnership(address newOwner) onlyOwner {
        owner = newOwner;
    }
}

contract Congress is owned {

    /* Contract Variables and events */
    uint public minimumQuorum;
    uint public debatingPeriodInMinutes;
    int public majorityMargin;
    Proposal[] public proposals;
    uint public numProposals;
    mapping (address => uint) public memberId;
    Member[] public members;

    event ProposalAdded(uint proposalID, address recipient, uint amount, string description);
    event Voted(uint proposalID, bool position, address voter, string justification);
    event ProposalTallied(uint proposalID, int result, uint quorum, bool active);
    event MembershipChanged(address member, bool isMember);
    event ChangeOfRules(uint minimumQuorum, uint debatingPeriodInMinutes, int majorityMargin);
    
    struct Proposal {
        address recipient;
        uint amount;
        string description;
        uint votingDeadline;
        bool executed;
        bool proposalPassed;
        uint numberOfVotes;
        int currentResult;
        bytes32 proposalHash;
        Vote[] votes;
        mapping (address => bool) voted;
    }
    
    struct Member {
        address member;
        bool canVote;
        string name;
        uint memberSince;
    }

    struct Vote {
        bool inSupport;
        address voter;
        string justification;
    }
    
    /* modifier that allows only shareholders to vote and create new proposals */
    modifier onlyMembers {
        if (memberId[msg.sender] == 0 
        || !members[memberId[msg.sender]].canVote) 
        throw;
        _
    }
    
    /* First time setup */
    function Congress(uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority, address congressLeader) {
        minimumQuorum = minimumQuorumForProposals;
        debatingPeriodInMinutes = minutesForDebate;
        majorityMargin = marginOfVotesForMajority;
        members.length++;
        members[0] = Member({member: 0, canVote: false, memberSince: now, name: ''});
        if (congressLeader != 0) owner = congressLeader;

    }
    
    /*make member*/
    function changeMembership(address targetMember, bool canVote, string memberName) onlyOwner {
        uint id;
        if (memberId[targetMember] == 0) {
           memberId[targetMember] = members.length;
           id = members.length++;
           members[id] = Member({member: targetMember, canVote: canVote, memberSince: now, name: memberName});
        } else {
            id = memberId[targetMember];
            Member m = members[id];
            m.canVote = canVote;
        }
        
        MembershipChanged(targetMember, canVote);

    }
    
    /*change rules*/
    function changeVotingRules(uint minimumQuorumForProposals, uint minutesForDebate, int marginOfVotesForMajority) onlyOwner {
        minimumQuorum = minimumQuorumForProposals;
        debatingPeriodInMinutes = minutesForDebate;
        majorityMargin = marginOfVotesForMajority;
        
        ChangeOfRules(minimumQuorum, debatingPeriodInMinutes, majorityMargin);
    }

    /* Function to create a new proposal */
    function newProposal(address beneficiary, uint etherAmount, string JobDescription, bytes transactionBytecode) onlyMembers returns (uint proposalID) {
        proposalID = proposals.length++;
        Proposal p = proposals[proposalID];
        p.recipient = beneficiary;
        p.amount = etherAmount;
        p.description = JobDescription;
        p.proposalHash = sha3(beneficiary, etherAmount, transactionBytecode);
        p.votingDeadline = now + debatingPeriodInMinutes * 1 minutes;
        p.executed = false;
        p.proposalPassed = false;
        p.numberOfVotes = 0;
        ProposalAdded(proposalID, beneficiary, etherAmount, JobDescription);
        numProposals = proposalID+1;
    }
    
    /* function to check if a proposal code matches */
    function checkProposalCode(uint proposalNumber, address beneficiary, uint etherAmount, bytes transactionBytecode) constant returns (bool codeChecksOut) {
        Proposal p = proposals[proposalNumber];
        return p.proposalHash == sha3(beneficiary, etherAmount, transactionBytecode);
    }
    
    function vote(uint proposalNumber, bool supportsProposal, string justificationText) onlyMembers returns (uint voteID){
        Proposal p = proposals[proposalNumber];         // Get the proposal
        if (p.voted[msg.sender] == true) throw;         // If has already voted, cancel
        p.voted[msg.sender] = true;                     // Set this voter as having voted
        p.numberOfVotes++;                              // Increase the number of votes
        if (supportsProposal) {                         // If they support the proposal
            p.currentResult++;                          // Increase score
        } else {                                        // If they don't
            p.currentResult--;                          // Decrease the score
        }
        // Create a log of this event
        Voted(proposalNumber,  supportsProposal, msg.sender, justificationText);
    }

    function executeProposal(uint proposalNumber, bytes transactionBytecode) returns (int result) {
        Proposal p = proposals[proposalNumber];
        /* Check if the proposal can be executed */
        if (now < p.votingDeadline                                                  // has the voting deadline arrived?  
            || p.executed                                                           // has it been already executed? 
            || p.proposalHash != sha3(p.recipient, p.amount, transactionBytecode)   // Does the transaction code match the proposal? 
            || p.numberOfVotes <= minimumQuorum)                                    // has minimum quorum?
            throw;
        
        /* execute result */
        if (p.currentResult > majorityMargin) {     
            /* If difference between support and opposition is larger than margin */
            p.recipient.call.value(p.amount*1000000000000000000)(transactionBytecode);
            p.executed = true;
            p.proposalPassed = true;
        } else {
            p.executed = true;
            p.proposalPassed = false;
        } 
        // Fire Events
        ProposalTallied(proposalNumber, p.currentResult, p.numberOfVotes, p.proposalPassed);
    }
}

External Links