SingularDTV Crowdsale Completed Within Fifteen Minutes

SingularDTV Crowdsale Completed Within Fifteen Minutes and SingularDTV Raises $7.5M to Incentivize Creative Output.

Website – https://singulardtv.com/.
Reddit – https://www.reddit.com/r/SingularDTV.

From the reddit site sidebar:

TOKEN SALE SPECS

The SingularDTV token is called “SNGLS”. SNGLS are fungible and conform to Ethereum’s universal token standards. SNGLS represent a pro rata gross revenue/asset share in SingularDTV projects and intellectual property.

The total number of SNGLS in the SingularDTV ecosystem is 1 Billion. 500 million of these will be generated for the SingularDTV audience at the ETH equivalent of 1.5 cents per token for a total ETH equivalent of $7.5m to:

1.) launch a documentary film division dedicated to educating the world about Ethereum, blockchain and decentralization;

2.) produce Season 1 of our sci-fi epic television series ‘Singular’, about the human race’s journey into a technological Singularity;

3.) build a rights, revenue and royalty management platform and;

4.) build a transaction video on-demand portal.

Of the remaining 500 million SNGLS tokens not offered to the world, 400 million belong to the founders and 100 million to seed/development investors. All gross revenue claimed by the 400 million founders tokens will be re-invested back into the SingularDTV ecosystem to create film/TV content as well as decentralized tech/apps for the entertainment industry. It is important to note the SingularDTV founders will only receive dividends or revenue from these 400 million tokens in the event of a future exit. Founders will receive commensurate compensation as budgeted on a per project basis to act as SingularDTV’s executive team. The remaining 100 million tokens held by our seed/development investors enjoy the same attributes as the 500 million sold to the world. They can be held to receive revenue and asset benefits from SingularDTV projects in perpetuity, or traded on the open market. Please see our Summary Overview on www.SingularDTV.com for more details or please ask us anything.

The tokens were apparently on sale for 862.065 SNGL per 1 ETH. 1 ETH = USD 13.208 currently. 1 SNGL = ~USD 13.208 / 862.065 = ~ USD 0.015 . Which is approximately 1.5 cents per SNGL.

At 1 ETH = 0.02160640 BTC, 1 SNGL = ~ 0.00002506 BTC.

The contract code at https://github.com/ConsenSys/singulardtv-contracts listed below:

AbstractCampaign.sol

contract Campaign {
    /// @notice the campaign name
    /// @return contractual metadata which specifies the campaign name as a string
    function name() constant returns(string) {}

    /// @notice use to determine the contribution method abi
    /// @return will return a string that is the exact contributeMethodABI
    function contributeMethodABI() constant returns(string) {}

    /// @notice use to determine the contribution method abi
    /// @return will return a string that is the exact contributeMethodABI
    function refundMethodABI() constant returns(string) {}

    /// @notice use to determine the contribution method abi
    /// @return will return a string that is the exact contributeMethodABI
    function payoutMethodABI() constant returns(string) {}

    /// @notice use to determine the beneficiary destination for the campaign
    /// @return the beneficiary address that will receive the campaign payout
    function beneficiary() constant returns(address) {}

    /// @notice the time at which the campaign fails or succeeds
    /// @return the uint unix timestamp at which time the campaign expires
    function expiry() constant returns(uint256 timestamp) {}

    /// @notice the goal the campaign must reach in order for it to succeed
    /// @return the campaign funding goal specified in wei as a uint256
    function fundingGoal() constant returns(uint256 amount) {}

    /// @notice the goal the campaign must reach in order for it to succeed
    /// @return the campaign funding goal specified in wei as a uint256
    function amountRaised() constant returns(uint256 amount) {}

    // Campaign events
    event ContributionMade (address _contributor);
    event RefundPayoutClaimed(uint256 _contributionID);
    event BeneficiaryPayoutClaimed (address _beneficiary, uint256 _payoutAmount);
}

AbstractToken.sol

/// Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/issues/20

/// @title Abstract token contract - Functions to be implemented by token contracts.
/// @author Stefan George - <stefan.george@consensys.net>
contract Token {
    // This is not an abstract function, because solc won't recognize generated getter functions for public variables as functions
    function totalSupply() constant returns (uint256 supply) {}
    function balanceOf(address owner) constant returns (uint256 balance);
    function transfer(address to, uint256 value) returns (bool success);
    function transferFrom(address from, address to, uint256 value) returns (bool success);
    function approve(address spender, uint256 value) returns (bool success);
    function allowance(address owner, address spender) constant returns (uint256 remaining);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

AbstractSingularDTVToken.sol

import "AbstractToken.sol";

contract SingularDTVToken is Token {
    function issueTokens(address _for, uint tokenCount) returns (bool);
}

AbstractSingularDTVFund.sol

contract SingularDTVFund {
    function workshop() returns (address);
    function softWithdrawRevenueFor(address forAddress) returns (uint);
}

AbstractSingularDTVCrowdfunding.sol

contract SingularDTVCrowdfunding {
    function twoYearsPassed() returns (bool);
    function startDate() returns (uint);
    function CROWDFUNDING_PERIOD() returns (uint);
    function TOKEN_TARGET() returns (uint);
    function valuePerShare() returns (uint);
    function fundBalance() returns (uint);
    function campaignEndedSuccessfully() returns (bool);
}

SingularDTVFund.sol

import "AbstractSingularDTVToken.sol";
import "AbstractSingularDTVCrowdfunding.sol";


/// @title Fund contract - Implements revenue distribution.
/// @author Stefan George - <stefan.george@consensys.net>
contract SingularDTVFund {

    /*
     *  External contracts
     */
    SingularDTVToken public singularDTVToken;
    SingularDTVCrowdfunding public singularDTVCrowdfunding;

    /*
     *  Storage
     */
    address public owner;
    address constant public workshop = {{MistWallet}};
    uint public totalRevenue;

    // User's address => Revenue at time of withdraw
    mapping (address => uint) public revenueAtTimeOfWithdraw;

    // User's address => Revenue which can be withdrawn
    mapping (address => uint) public owed;

    /*
     *  Modifiers
     */
    modifier noEther() {
        if (msg.value > 0) {
            throw;
        }
        _
    }

    modifier onlyOwner() {
        // Only guard is allowed to do this action.
        if (msg.sender != owner) {
            throw;
        }
        _
    }

    modifier campaignEndedSuccessfully() {
        if (!singularDTVCrowdfunding.campaignEndedSuccessfully()) {
            throw;
        }
        _
    }

    /*
     *  Contract functions
     */
    /// @dev Deposits revenue. Returns success.
    function depositRevenue()
        external
        campaignEndedSuccessfully
        returns (bool)
    {
        totalRevenue += msg.value;
        return true;
    }

    /// @dev Withdraws revenue share for user. Returns revenue share.
    /// @param forAddress Shareholder's address.
    function calcRevenue(address forAddress) internal returns (uint) {
        return singularDTVToken.balanceOf(forAddress) * (totalRevenue - revenueAtTimeOfWithdraw[forAddress]) / singularDTVToken.totalSupply();
    }

    /// @dev Withdraws revenue share for user. Returns revenue share.
    function withdrawRevenue()
        external
        noEther
        returns (uint)
    {
        uint value = calcRevenue(msg.sender) + owed[msg.sender];
        revenueAtTimeOfWithdraw[msg.sender] = totalRevenue;
        owed[msg.sender] = 0;
        if (value > 0 && !msg.sender.send(value)) {
            throw;
        }
        return value;
    }

    /// @dev Credits revenue share to owed balance.
    /// @param forAddress Shareholder's address.
    function softWithdrawRevenueFor(address forAddress)
        external
        noEther
        returns (uint)
    {
        uint value = calcRevenue(forAddress);
        revenueAtTimeOfWithdraw[forAddress] = totalRevenue;
        owed[forAddress] += value;
        return value;
    }

    /// @dev Setup function sets external contracts' addresses.
    /// @param singularDTVTokenAddress Token address.
    function setup(address singularDTVCrowdfundingAddress, address singularDTVTokenAddress)
        external
        noEther
        onlyOwner
        returns (bool)
    {
        if (address(singularDTVCrowdfunding) == 0 && address(singularDTVToken) == 0) {
            singularDTVCrowdfunding = SingularDTVCrowdfunding(singularDTVCrowdfundingAddress);
            singularDTVToken = SingularDTVToken(singularDTVTokenAddress);
            return true;
        }
        return false;
    }

    /// @dev Contract constructor function sets guard and initial token balances.
    function SingularDTVFund() noEther {
        // Set owner address
        owner = msg.sender;
    }
}

SingularDTVCrowdfunding.sol

Contract deployed at 0xbdf5c4f1c1a9d7335a6a68d9aa011d5f40cf5520.

import "AbstractSingularDTVToken.sol";
import "AbstractSingularDTVFund.sol";


/// @title Crowdfunding contract - Implements crowdfunding functionality.
/// @author Stefan George - <stefan.george@consensys.net>
contract SingularDTVCrowdfunding {

    /*
     *  External contracts
     */
    SingularDTVToken public singularDTVToken;
    SingularDTVFund public singularDTVFund;

    /*
     *  Constants
     */
    uint constant public CAP = 1000000000; // 1B tokens is the maximum amount of tokens
    uint constant public CROWDFUNDING_PERIOD = 4 weeks; // 1 month
    uint constant public TOKEN_LOCKING_PERIOD = 2 years; // 2 years
    uint constant public TOKEN_TARGET = 534000000; // 34M Tokens more than the initial 500M, around 42,500 ETH

    /*
     *  Enums
     */
    enum Stages {
        CrowdfundingGoingAndGoalNotReached,
        CrowdfundingEndedAndGoalNotReached,
        CrowdfundingGoingAndGoalReached,
        CrowdfundingEndedAndGoalReached
    }

    /*
     *  Storage
     */
    address public owner;
    uint public startDate;
    uint public fundBalance;
    uint public baseValue = 1250 szabo; // 0.00125 ETH
    uint public valuePerShare = baseValue; // 0.00125 ETH

    // investor address => investment in Wei
    mapping (address => uint) public investments;

    // Initialize stage
    Stages public stage = Stages.CrowdfundingGoingAndGoalNotReached;

    /*
     *  Modifiers
     */
    modifier noEther() {
        if (msg.value > 0) {
            throw;
        }
        _
    }

    modifier onlyOwner() {
        // Only owner is allowed to do this action.
        if (msg.sender != owner) {
            throw;
        }
        _
    }

    modifier minInvestment() {
        // User has to invest at least the ether value of one share.
        if (msg.value < valuePerShare) {
            throw;
        }
        _
    }

    modifier atStage(Stages _stage) {
        if (stage != _stage) {
            throw;
        }
        _
    }

    modifier atStageOR(Stages _stage1, Stages _stage2) {
        if (stage != _stage1 && stage != _stage2) {
            throw;
        }
        _
    }

    modifier timedTransitions() {
        uint crowdfundDuration = now - startDate;
        if (crowdfundDuration >= 22 days) {
            valuePerShare = baseValue * 1500 / 1000;
        }
        else if (crowdfundDuration >= 18 days) {
            valuePerShare = baseValue * 1375 / 1000;
        }
        else if (crowdfundDuration >= 14 days) {
            valuePerShare = baseValue * 1250 / 1000;
        }
        else if (crowdfundDuration >= 10 days) {
            valuePerShare = baseValue * 1125 / 1000;
        }
        else {
            valuePerShare = baseValue;
        }
        if (crowdfundDuration >= CROWDFUNDING_PERIOD) {
            if (stage == Stages.CrowdfundingGoingAndGoalNotReached) {
                stage = Stages.CrowdfundingEndedAndGoalNotReached;
            }
            else if (stage == Stages.CrowdfundingGoingAndGoalReached) {
                stage = Stages.CrowdfundingEndedAndGoalReached;
            }
        }
        _
    }

    /*
     *  Contract functions
     */
    /// dev Validates invariants.
    function checkInvariants() constant internal {
        if (fundBalance > this.balance) {
            throw;
        }
    }

    /// @dev Can be triggered if an invariant fails.
    function emergencyCall()
        external
        noEther
        returns (bool)
    {
        if (fundBalance > this.balance) {
            if (this.balance > 0 && !singularDTVFund.workshop().send(this.balance)) {
                throw;
            }
            return true;
        }
        return false;
    }

    /// @dev Allows user to fund the campaign if campaign is still going and cap not reached. Returns share count.
    function fund()
        external
        timedTransitions
        atStageOR(Stages.CrowdfundingGoingAndGoalNotReached, Stages.CrowdfundingGoingAndGoalReached)
        minInvestment
        returns (uint)
    {
        uint tokenCount = msg.value / valuePerShare; // Token count is rounded down. Investment should be multiples of valuePerShare.
        if (singularDTVToken.totalSupply() + tokenCount > CAP) {
            // User wants to buy more shares than available. Set shares to possible maximum.
            tokenCount = CAP - singularDTVToken.totalSupply();
        }
        uint investment = tokenCount * valuePerShare; // Ether invested by backer.
        // Send change back to user.
        if (msg.value > investment && !msg.sender.send(msg.value - investment)) {
            throw;
        }
        // Update fund's and user's balance and total supply of shares.
        fundBalance += investment;
        investments[msg.sender] += investment;
        if (!singularDTVToken.issueTokens(msg.sender, tokenCount)) {
            // Tokens could not be issued.
            throw;
        }
        // Update stage
        if (stage == Stages.CrowdfundingGoingAndGoalNotReached) {
            if (singularDTVToken.totalSupply() >= TOKEN_TARGET) {
                stage = Stages.CrowdfundingGoingAndGoalReached;
            }
        }
        // not an else clause for the edge case that the CAP and TOKEN_TARGET are reached with one big funding
        if (stage == Stages.CrowdfundingGoingAndGoalReached) {
            if (singularDTVToken.totalSupply() == CAP) {
                stage = Stages.CrowdfundingEndedAndGoalReached;
            }
        }
        checkInvariants();
        return tokenCount;
    }

    /// @dev Allows user to withdraw his funding if crowdfunding ended and target was not reached. Returns success.
    function withdrawFunding()
        external
        noEther
        timedTransitions
        atStage(Stages.CrowdfundingEndedAndGoalNotReached)
        returns (bool)
    {
        // Update fund's and user's balance and total supply of shares.
        uint investment = investments[msg.sender];
        investments[msg.sender] = 0;
        fundBalance -= investment;
        // Send funds back to user.
        if (investment > 0  && !msg.sender.send(investment)) {
            throw;
        }
        checkInvariants();
        return true;
    }

    /// @dev Withdraws funding for workshop. Returns success.
    function withdrawForWorkshop()
        external
        noEther
        timedTransitions
        atStage(Stages.CrowdfundingEndedAndGoalReached)
        returns (bool)
    {
        uint value = fundBalance;
        fundBalance = 0;
        if (value > 0  && !singularDTVFund.workshop().send(value)) {
            throw;
        }
        checkInvariants();
        return true;
    }

    /// @dev Sets token value in Wei.
    /// @param valueInWei New value.
    function changeBaseValue(uint valueInWei)
        external
        noEther
        onlyOwner
        returns (bool)
    {
        baseValue = valueInWei;
        return true;
    }

    /// @dev Returns if 1 year passed since beginning of crowdfunding.
    function twoYearsPassed()
        constant
        external
        noEther
        returns (bool)
    {
        return now - startDate >= TOKEN_LOCKING_PERIOD;
    }

    /// @dev Returns if campaign ended successfully.
    function campaignEndedSuccessfully()
        constant
        external
        noEther
        returns (bool)
    {
        if (stage == Stages.CrowdfundingEndedAndGoalReached) {
            return true;
        }
        return false;
    }

    // updateStage allows calls to receive correct stage. It can be used for transactions but is not part of the regular crowdfunding routine.
    // It is not marked as constant because timedTransitions modifier is altering state and constant is not yet enforced by solc.
    /// @dev returns correct stage, even if a function with timedTransitions modifier has not yet been called successfully.
    function updateStage()
        external
        timedTransitions
        noEther
        returns (Stages)
    {
        return stage;
    }

    /// @dev Setup function sets external contracts' addresses.
    /// @param singularDTVFundAddress Crowdfunding address.
    /// @param singularDTVTokenAddress Token address.
    function setup(address singularDTVFundAddress, address singularDTVTokenAddress)
        external
        onlyOwner
        noEther
        returns (bool)
    {
        if (address(singularDTVFund) == 0 && address(singularDTVToken) == 0) {
            singularDTVFund = SingularDTVFund(singularDTVFundAddress);
            singularDTVToken = SingularDTVToken(singularDTVTokenAddress);
            return true;
        }
        return false;
    }

    /// @dev Contract constructor function sets owner and start date.
    function SingularDTVCrowdfunding() noEther {
        // Set owner address
        owner = msg.sender;
        // Set start-date of crowdfunding
        startDate = now;
    }

    /// @dev Fallback function always fails. Use fund function to fund the contract with Ether.
    function () {
        throw;
    }
}

 

StandardToken.sol

import "AbstractToken.sol";


contract StandardToken is Token {

    /*
     *  Data structures
     */
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;
    uint256 public totalSupply;

    /*
     *  Read and write storage functions
     */
    /// @dev Transfers sender's tokens to a given address. Returns success.
    /// @param _to Address of token receiver.
    /// @param _value Number of tokens to transfer.
    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] >= _value && _value > 0) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        }
        else {
            return false;
        }
    }

    /// @dev Allows allowed third party to transfer tokens from one address to another. Returns success.
    /// @param _from Address from where tokens are withdrawn.
    /// @param _to Address to where tokens are sent.
    /// @param _value Number of tokens to transfer.
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
            balances[_to] += _value;
            balances[_from] -= _value;
            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        }
        else {
            return false;
        }
    }

    /// @dev Returns number of tokens owned by given address.
    /// @param _owner Address of token owner.
    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    /// @dev Sets approved amount of tokens for spender. Returns success.
    /// @param _spender Address of allowed account.
    /// @param _value Number of approved tokens.
    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    /*
     * Read storage functions
     */
    /// @dev Returns number of allowed tokens for given address.
    /// @param _owner Address of token owner.
    /// @param _spender Address of token spender.
    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
      return allowed[_owner][_spender];
    }

}

 

SingularDTVToken.sol

Contract deployed at 0xaec2e87e0a235266d9c5adc9deb4b2e29b54d009.

import "StandardToken.sol";
import "AbstractSingularDTVFund.sol";
import "AbstractSingularDTVCrowdfunding.sol";


/// @title Token contract - Implements token issuance.
/// @author Stefan George - 
contract SingularDTVToken is StandardToken {

    /*
     *  External contracts
     */
    SingularDTVFund constant singularDTVFund = SingularDTVFund({{SingularDTVFund}});
    SingularDTVCrowdfunding constant singularDTVCrowdfunding = SingularDTVCrowdfunding({{SingularDTVCrowdfunding}});

    /*
     *  Token meta data
     */
    string constant public name = "SingularDTV";
    string constant public symbol = "SNGLS";
    uint8 constant public decimals = 0;

    /*
     *  Modifiers
     */
    modifier noEther() {
        if (msg.value > 0) {
            throw;
        }
        _
    }

    modifier workshopWaitedTwoYears() {
        // Workshop can only transfer shares after a two years period.
        if (msg.sender == singularDTVFund.workshop() && !singularDTVCrowdfunding.twoYearsPassed()) {
            throw;
        }
        _
    }

    modifier isCrowdfundingContract () {
        // Only crowdfunding contract is allowed to proceed.
        if (msg.sender != address(singularDTVCrowdfunding)) {
            throw;
        }
        _
    }

    /*
     *  Contract functions
     */
    /// @dev Crowdfunding contract issues new tokens for address. Returns success.
    /// @param _for Address of receiver.
    /// @param tokenCount Number of tokens to issue.
    function issueTokens(address _for, uint tokenCount)
        external
        isCrowdfundingContract
        returns (bool)
    {
        if (tokenCount == 0) {
            return false;
        }
        balances[_for] += tokenCount;
        totalSupply += tokenCount;
        return true;
    }

    /// @dev Transfers sender's tokens to a given address. Returns success.
    /// @param to Address of token receiver.
    /// @param value Number of tokens to transfer.
    function transfer(address to, uint256 value)
        noEther
        workshopWaitedTwoYears
        returns (bool)
    {
        // Both parties withdraw their revenue first
        singularDTVFund.softWithdrawRevenueFor(msg.sender);
        singularDTVFund.softWithdrawRevenueFor(to);
        return super.transfer(to, value);
    }

    /// @dev Allows allowed third party to transfer tokens from one address to another. Returns success.
    /// @param from Address from where tokens are withdrawn.
    /// @param to Address to where tokens are sent.
    /// @param value Number of tokens to transfer.
    function transferFrom(address from, address to, uint256 value)
        noEther
        workshopWaitedTwoYears
        returns (bool)
    {
        // Both parties withdraw their revenue first
        singularDTVFund.softWithdrawRevenueFor(from);
        singularDTVFund.softWithdrawRevenueFor(to);
        return super.transferFrom(from, to, value);
    }

    /// @dev Contract constructor function sets initial token balances.
    function SingularDTVToken() noEther {
        // Set initial share distribution
        balances[singularDTVFund.workshop()] = 400000000; // ~400M
        // Series A investors
        balances[0x0196b712a0459cbee711e7c1d34d2c85a9910379] = 5000000;
        balances[0x0f94dc84ce0f5fa2a8cc8d27a6969e25b5a39273] = 200000;
        balances[0x122b7eb5f629d806c8adb0baa0560266abb3ec80] = 450000;
        balances[0x13870d30fcdb7d7ae875668f2a1219225295d57c] = 50000;
        balances[0x26640e826547bc700b8c7a9cc2c1c39a4ab3cbb3] = 900000;
        balances[0x26bbfc6b23bc36e84447f061c6804f3a8b1a3698] = 250000;
        balances[0x2d37383a45b5122a27efade69f7180eee4d965da] = 1270000;
        balances[0x2e79b81121193d55c4934c0f32ad3d0474ca7b9c] = 4200000;
        balances[0x3114844fc0e3de03963bbd1d983ba17ca89ad010] = 5000000;
        balances[0x378e6582e4e3723f7076c7769eef6febf51258e1] = 680000;
        balances[0x3e18530a4ee49a0357ffc8e74c08bfdee3915482] = 2490000;
        balances[0x43fed1208d25ca0ef5681a5c17180af50c19f826] = 100000;
        balances[0x4f183b18302c0ac5804b8c455018efc51af15a56] = 10000;
        balances[0x55a886834658ccb6f26c39d5fdf6d833df3a276a] = 100000;
        balances[0x5faa1624422db662c654ab35ce57bf3242888937] = 5000000;
        balances[0x6407b662b306e2353b627488da952337a5a0bbaa] = 5000000;
        balances[0x66c334fff8c8b8224b480d8da658ca3b032fe625] = 10000000;
        balances[0x6c24991c6a40cd5ad6fab78388651fb324b35458] = 250000;
        balances[0x781ba492f786b2be48c2884b733874639f50022c] = 500000;
        balances[0x79b48f6f1ac373648c509b74a2c04a3281066457] = 2000000;
        balances[0x835898804ed30e20aa29f2fe35c9f225175b049f] = 100000;
        balances[0x93c56ea8848150389e0917de868b0a23c87cf7b1] = 2790000;
        balances[0x93f959df3df3c6ee01ee9748327b881b2137bf2a] = 450000;
        balances[0x9adc0215372e4ffd8c89621a6bd9cfddf230349f] = 550000;
        balances[0xae4dbd3dae66722315541d66fe9457b342ac76d9] = 500000;
        balances[0xbae02fe006f115e45b372f2ddc053eedca2d6fff] = 1800000;
        balances[0xcc835821f643e090d8157de05451b416cd1202c4] = 300000;
        balances[0xce75342b92a7d0b1a2c6e9835b6b85787e12e585] = 670000;
        balances[0xd2b388467d9d0c30bab0a68070c6f49c473583a0] = 990000;
        balances[0xdca0724ddde95bbace1b557cab4375d9a813da49] = 3500000;
        balances[0xe3ef62165b60cac0fcbe9c2dc6a03aab4c5c8462] = 150000;
        balances[0xe4f7d5083baeea7810b6d816581bb0ee7cd4b6f4] = 10560000;
        balances[0xef08eb55d3482973c178b02bd4d5f2cea420325f] = 80000;
        balances[0xfdecc9f2ee374cedc94f72ab4da2de896ce58c19] = 5000000;
        balances[0xe5ff71dc1dea8cd2552eec59e9a5e8813da9bb01] = 29110000;
        totalSupply = 500000000; // 500M
    }
}

 

SingularDTVWeifund.sol

import "AbstractCampaign.sol";
import "AbstractSingularDTVFund.sol";
import "AbstractSingularDTVCrowdfunding.sol";


/// @title Crowdfunding contract - Implements crowdfunding functionality.
/// @author Stefan George - 
contract SingularDTVWeifund is Campaign {

    /*
     *  External contracts
     */
    SingularDTVFund constant singularDTVFund = SingularDTVFund({{SingularDTVFund}});
    SingularDTVCrowdfunding constant singularDTVCrowdfunding = SingularDTVCrowdfunding({{SingularDTVCrowdfunding}});

    string constant public name = "SingularDTV Campaign";
    string constant public contributeMethodABI = "fund()";
    string constant public refundMethodABI = "withdrawFunding()";
    string constant public payoutMethodABI = "withdrawForWorkshop()";

    /// @notice use to determine the beneficiary destination for the campaign
    /// @return the beneficiary address that will receive the campaign payout
    function beneficiary() constant returns(address) {
        return singularDTVFund.workshop();
    }

    /// @notice the time at which the campaign fails or succeeds
    /// @return the uint unix timestamp at which time the campaign expires
    function expiry() constant returns(uint256 timestamp) {
        return singularDTVCrowdfunding.startDate() + singularDTVCrowdfunding.CROWDFUNDING_PERIOD();
    }

    /// @notice the goal the campaign must reach in order for it to succeed
    /// @return the campaign funding goal specified in wei as a uint256
    function fundingGoal() constant returns(uint256 amount) {
        return singularDTVCrowdfunding.TOKEN_TARGET() * singularDTVCrowdfunding.valuePerShare();
    }

    /// @notice the goal the campaign must reach in order for it to succeed
    /// @return the campaign funding goal specified in wei as a uint256
    function amountRaised() constant returns(uint256 amount) {
        return singularDTVCrowdfunding.fundBalance();
    }
}

 

MistWallet.sol

//sol Wallet
// Multi-sig, daily-limited account proxy/wallet.
// @authors:
// Gav Wood 
// inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a
// single, or, crucially, each of a number of, designated owners.
// usage:
// use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by
// some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the
// interior is executed.
contract multiowned {

	// TYPES

    // struct for the status of a pending operation.
    struct PendingState {
        uint yetNeeded;
        uint ownersDone;
        uint index;
    }

	// EVENTS

    // this contract only has five types of events: it can accept a confirmation, in which case
    // we record owner and operation (hash) alongside it.
    event Confirmation(address owner, bytes32 operation);
    event Revoke(address owner, bytes32 operation);
    // some others are in the case of an owner changing.
    event OwnerChanged(address oldOwner, address newOwner);
    event OwnerAdded(address newOwner);
    event OwnerRemoved(address oldOwner);
    // the last one is emitted if the required signatures change
    event RequirementChanged(uint newRequirement);

	// MODIFIERS

    // simple single-sig function modifier.
    modifier onlyowner {
        if (isOwner(msg.sender))
            _
    }
    // multi-sig function modifier: the operation must have an intrinsic hash in order
    // that later attempts can be realised as the same underlying operation and
    // thus count as confirmations.
    modifier onlymanyowners(bytes32 _operation) {
        if (confirmAndCheck(_operation))
            _
    }

	// METHODS

    // constructor is given number of sigs required to do protected "onlymanyowners" transactions
    // as well as the selection of addresses capable of confirming them.
    function multiowned(address[] _owners, uint _required) {
        m_numOwners = _owners.length + 1;
        m_owners[1] = uint(msg.sender);
        m_ownerIndex[uint(msg.sender)] = 1;
        for (uint i = 0; i < _owners.length; ++i)
        {
            m_owners[2 + i] = uint(_owners[i]);
            m_ownerIndex[uint(_owners[i])] = 2 + i;
        }
        m_required = _required;
    }
    
    // Revokes a prior confirmation of the given operation
    function revoke(bytes32 _operation) external {
        uint ownerIndex = m_ownerIndex[uint(msg.sender)];
        // make sure they're an owner
        if (ownerIndex == 0) return;
        uint ownerIndexBit = 2**ownerIndex;
        var pending = m_pending[_operation];
        if (pending.ownersDone & ownerIndexBit > 0) {
            pending.yetNeeded++;
            pending.ownersDone -= ownerIndexBit;
            Revoke(msg.sender, _operation);
        }
    }
    
    // Replaces an owner `_from` with another `_to`.
    function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data)) external {
        if (isOwner(_to)) return;
        uint ownerIndex = m_ownerIndex[uint(_from)];
        if (ownerIndex == 0) return;

        clearPending();
        m_owners[ownerIndex] = uint(_to);
        m_ownerIndex[uint(_from)] = 0;
        m_ownerIndex[uint(_to)] = ownerIndex;
        OwnerChanged(_from, _to);
    }
    
    function addOwner(address _owner) onlymanyowners(sha3(msg.data)) external {
        if (isOwner(_owner)) return;

        clearPending();
        if (m_numOwners >= c_maxOwners)
            reorganizeOwners();
        if (m_numOwners >= c_maxOwners)
            return;
        m_numOwners++;
        m_owners[m_numOwners] = uint(_owner);
        m_ownerIndex[uint(_owner)] = m_numOwners;
        OwnerAdded(_owner);
    }
    
    function removeOwner(address _owner) onlymanyowners(sha3(msg.data)) external {
        uint ownerIndex = m_ownerIndex[uint(_owner)];
        if (ownerIndex == 0) return;
        if (m_required > m_numOwners - 1) return;

        m_owners[ownerIndex] = 0;
        m_ownerIndex[uint(_owner)] = 0;
        clearPending();
        reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot
        OwnerRemoved(_owner);
    }
    
    function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data)) external {
        if (_newRequired > m_numOwners) return;
        m_required = _newRequired;
        clearPending();
        RequirementChanged(_newRequired);
    }
    
    function isOwner(address _addr) returns (bool) {
        return m_ownerIndex[uint(_addr)] > 0;
    }
    
    function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {
        var pending = m_pending[_operation];
        uint ownerIndex = m_ownerIndex[uint(_owner)];

        // make sure they're an owner
        if (ownerIndex == 0) return false;

        // determine the bit to set for this owner.
        uint ownerIndexBit = 2**ownerIndex;
        return !(pending.ownersDone & ownerIndexBit == 0);
    }
    
    // INTERNAL METHODS

    function confirmAndCheck(bytes32 _operation) internal returns (bool) {
        // determine what index the present sender is:
        uint ownerIndex = m_ownerIndex[uint(msg.sender)];
        // make sure they're an owner
        if (ownerIndex == 0) return;

        var pending = m_pending[_operation];
        // if we're not yet working on this operation, switch over and reset the confirmation status.
        if (pending.yetNeeded == 0) {
            // reset count of confirmations needed.
            pending.yetNeeded = m_required;
            // reset which owners have confirmed (none) - set our bitmap to 0.
            pending.ownersDone = 0;
            pending.index = m_pendingIndex.length++;
            m_pendingIndex[pending.index] = _operation;
        }
        // determine the bit to set for this owner.
        uint ownerIndexBit = 2**ownerIndex;
        // make sure we (the message sender) haven't confirmed this operation previously.
        if (pending.ownersDone & ownerIndexBit == 0) {
            Confirmation(msg.sender, _operation);
            // ok - check if count is enough to go ahead.
            if (pending.yetNeeded <= 1) {
                // enough confirmations: reset and run interior.
                delete m_pendingIndex[m_pending[_operation].index];
                delete m_pending[_operation];
                return true;
            }
            else
            {
                // not enough: record that this owner in particular confirmed.
                pending.yetNeeded--;
                pending.ownersDone |= ownerIndexBit;
            }
        }
    }

    function reorganizeOwners() private {
        uint free = 1;
        while (free < m_numOwners)
        {
            while (free < m_numOwners && m_owners[free] != 0) free++;
            while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;
            if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
            {
                m_owners[free] = m_owners[m_numOwners];
                m_ownerIndex[m_owners[free]] = free;
                m_owners[m_numOwners] = 0;
            }
        }
    }
    
    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            if (m_pendingIndex[i] != 0)
                delete m_pending[m_pendingIndex[i]];
        delete m_pendingIndex;
    }
        
   	// FIELDS

    // the number of owners that must confirm the same operation before it is run.
    uint public m_required;
    // pointer used to find a free slot in m_owners
    uint public m_numOwners;
    
    // list of owners
    uint[256] m_owners;
    uint constant c_maxOwners = 250;
    // index on the list of owners to allow reverse lookup
    mapping(uint => uint) m_ownerIndex;
    // the ongoing operations.
    mapping(bytes32 => PendingState) m_pending;
    bytes32[] m_pendingIndex;
}

// inheritable "property" contract that enables methods to be protected by placing a linear limit (specifiable)
// on a particular resource per calendar day. is multiowned to allow the limit to be altered. resource that method
// uses is specified in the modifier.
contract daylimit is multiowned {

	// MODIFIERS

    // simple modifier for daily limit.
    modifier limitedDaily(uint _value) {
        if (underLimit(_value))
            _
    }

	// METHODS

    // constructor - stores initial daily limit and records the present day's index.
    function daylimit(uint _limit) {
        m_dailyLimit = _limit;
        m_lastDay = today();
    }
    // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
    function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external {
        m_dailyLimit = _newLimit;
    }
    // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
    function resetSpentToday() onlymanyowners(sha3(msg.data)) external {
        m_spentToday = 0;
    }
    
    // INTERNAL METHODS
    
    // checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and
    // returns true. otherwise just returns false.
    function underLimit(uint _value) internal onlyowner returns (bool) {
        // reset the spend limit if we're on a different day to last time.
        if (today() > m_lastDay) {
            m_spentToday = 0;
            m_lastDay = today();
        }
        // check to see if there's enough left - if so, subtract and return true.
        if (m_spentToday + _value >= m_spentToday && m_spentToday + _value <= m_dailyLimit) {
            m_spentToday += _value;
            return true;
        }
        return false;
    }
    // determines today's index.
    function today() private constant returns (uint) { return now / 1 days; }

	// FIELDS

    uint public m_dailyLimit;
    uint m_spentToday;
    uint m_lastDay;
}

// interface contract for multisig proxy contracts; see below for docs.
contract multisig {

	// EVENTS

    // logged events:
    // Funds has arrived into the wallet (record how much).
    event Deposit(address _from, uint value);
    // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).
    event SingleTransact(address owner, uint value, address to, bytes data);
    // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).
    event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);
    // Confirmation still needed for a transaction.
    event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data);
    
    // FUNCTIONS
    
    // TODO: document
    function changeOwner(address _from, address _to) external;
    function execute(address _to, uint _value, bytes _data) external returns (bytes32);
    function confirm(bytes32 _h) returns (bool);
}

// usage:
// bytes32 h = Wallet(w).from(oneOwner).transact(to, value, data);
// Wallet(w).from(anotherOwner).confirm(h);
contract Wallet is multisig, multiowned, daylimit {

	// TYPES

    // Transaction structure to remember details of transaction lest it need be saved for a later call.
    struct Transaction {
        address to;
        uint value;
        bytes data;
    }

    // METHODS

    // constructor - just pass on the owner array to the multiowned and
    // the limit to daylimit
    function Wallet(address[] _owners, uint _required, uint _daylimit)
            multiowned(_owners, _required) daylimit(_daylimit) {
    }
    
    // kills the contract sending everything to `_to`.
    function kill(address _to) onlymanyowners(sha3(msg.data)) external {
        suicide(_to);
    }
    
    // gets called when no other function matches
    function() {
        // just being sent some cash?
        if (msg.value > 0)
            Deposit(msg.sender, msg.value);
    }
    
    // Outside-visible transact entry point. Executes transacion immediately if below daily spend limit.
    // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
    // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
    // and _data arguments). They still get the option of using them if they want, anyways.
    function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 _r) {
        // first, take the opportunity to check that we're under the daily limit.
        if (underLimit(_value)) {
            SingleTransact(msg.sender, _value, _to, _data);
            // yes - just execute the call.
            _to.call.value(_value)(_data);
            return 0;
        }
        // determine our operation hash.
        _r = sha3(msg.data, block.number);
        if (!confirm(_r) && m_txs[_r].to == 0) {
            m_txs[_r].to = _to;
            m_txs[_r].value = _value;
            m_txs[_r].data = _data;
            ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
        }
    }
    
    // confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order
    // to determine the body of the transaction from the hash provided.
    function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
        if (m_txs[_h].to != 0) {
            m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data);
            MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data);
            delete m_txs[_h];
            return true;
        }
    }
    
    // INTERNAL METHODS
    
    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            delete m_txs[m_pendingIndex[i]];
        super.clearPending();
    }

	// FIELDS

    // pending transactions we have at present.
    mapping (bytes32 => Transaction) m_txs;
}
This entry was posted in Blog and tagged , , . Bookmark the permalink.