Sample Orphan Token

Sample Orphan Token

Orphan token want to be goes live

pragma solidity ^0.4.8;

// ----------------------------------------------------------------------------------------------
// Sample fixed supply token contract
// Enjoy. (c) BokkyPooBah 2017. The MIT Licence.
// ----------------------------------------------------------------------------------------------

// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/issues/20
contract ERC20Interface {
// Get the total token supply
function totalSupply() constant returns (uint256 totalSupply);

     // Get the account balance of another account with address _owner
     function balanceOf(address _owner) constant returns (uint256 balance);

     // Send _value amount of tokens to address _to
     function transfer(address _to, uint256 _value) returns (bool success);

     // Send _value amount of tokens from address _from to address _to
     function transferFrom(address _from, address _to, uint256 _value) returns (bool success);

     // Allow _spender to withdraw from your account, multiple times, up to the _value amount.
     // If this function is called again it overwrites the current allowance with _value.
     // this function is required for some DEX functionality
     function approve(address _spender, uint256 _value) returns (bool success);

     // Returns the amount which _spender is still allowed to withdraw from _owner
     function allowance(address _owner, address _spender) constant returns (uint256 remaining);

     // Triggered when tokens are transferred.
     event Transfer(address indexed _from, address indexed _to, uint256 _value);

     // Triggered whenever approve(address _spender, uint256 _value) is called.
     event Approval(address indexed _owner, address indexed _spender, uint256 _value);
 }

 contract OrphanToken is ERC20Interface {
     string public constant symbol = "OCT";
     string public constant name = "Orphan Token";
     uint8 public constant decimals = 18;
     uint256 _totalSupply = 1000000 * 18e10;

     // Owner of this contract
     address public owner;

     // Balances for each account
     mapping(address => uint256) balances;

     // Owner of account approves the transfer of an amount to another account
     mapping(address => mapping (address => uint256)) allowed;

     // Functions with this modifier can only be executed by the owner
     modifier onlyOwner() {
         require (msg.sender == owner);
         _;
     }

     // Constructor
     function FixedSupplyToken() {
         owner = msg.sender;
         balances[owner] = _totalSupply;
     }

     function totalSupply() constant returns (uint256 totalSupply) {
         totalSupply = _totalSupply;
     }

     // What is the balance of a particular account?
     function balanceOf(address _owner) constant returns (uint256 balance) {
         return balances[_owner];
     }

     // Transfer the balance from owner's account to another account
     function transfer(address _to, uint256 _amount) returns (bool success) {
         if (balances[msg.sender] >= _amount
             && _amount > 0
             && balances[_to] + _amount > balances[_to]) {
             balances[msg.sender] -= _amount;
             balances[_to] += _amount;
             Transfer(msg.sender, _to, _amount);
             return true;
         } else {
             return false;
         }
     }

     // Send _value amount of tokens from address _from to address _to
     // The transferFrom method is used for a withdraw workflow, allowing contracts to send
     // tokens on your behalf, for example to "deposit" to a contract address and/or to charge
     // fees in sub-currencies; the command should fail unless the _from account has
     // deliberately authorized the sender of the message via some mechanism; we propose
     // these standardized APIs for approval:
     function transferFrom(
         address _from,
         address _to,
         uint256 _amount
     ) returns (bool success) {
         if (balances[_from] >= _amount
             && allowed[_from][msg.sender] >= _amount
             && _amount > 0
             && balances[_to] + _amount > balances[_to]) {
             balances[_from] -= _amount;
             allowed[_from][msg.sender] -= _amount;
             balances[_to] += _amount;
             Transfer(_from, _to, _amount);
             return true;
         } else {
             return false;
         }
     }

     // Allow _spender to withdraw from your account, multiple times, up to the _value amount.
     // If this function is called again it overwrites the current allowance with _value.
     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];
     }
 }

contract Crowdsale {

    address public beneficiary;

    	uint public fundingGoal;
	uint public amountRaised;
	uint public deadline;
	uint public price;

    FixedSupplyToken public tokenReward;

    mapping(address => uint256) public balanceOf;

    bool fundingGoalReached = false;

    event GoalReached(address beneficiary, uint amountRaised);
    event FundTransfer(address backer, uint amount, bool isContribution);

    bool crowdsaleClosed = false;

    /* data structure to hold information about campaign contributors */

    /*  at initialization, setup the owner */
    function Crowdsale(
        address ifSuccessfulSendTo,
        uint fundingGoalInEthers,
        uint durationInMinutes,
        uint etherCostOfEachToken,
        FixedSupplyToken addressOfTokenUsedAsReward
    ) {
        beneficiary = ifSuccessfulSendTo;
        fundingGoal = fundingGoalInEthers * 1 ether;
        deadline = now + durationInMinutes * 1 minutes;
        price = etherCostOfEachToken * 1 ether;
        tokenReward = FixedSupplyToken(addressOfTokenUsedAsReward);
    }

    /* The function without name is the default function that is called whenever anyone sends funds to a contract */
    function () payable {
        require (!crowdsaleClosed);
        uint amount = amount + msg.value;
        balanceOf[msg.sender] += amount;
        amountRaised += amount;
        tokenReward.transfer(msg.sender, amount / price);
        FundTransfer(msg.sender, amount, true);
    }

    modifier afterDeadline() { if (now >= deadline) _; }

    /* checks if the goal or time limit has been reached and ends the campaign */
    function checkGoalReached() afterDeadline {
        if (amountRaised >= fundingGoal){
            fundingGoalReached = true;
            GoalReached(beneficiary, amountRaised);
        }
        crowdsaleClosed = true;
    }

    function safeWithdrawal() afterDeadline {
        if (!fundingGoalReached) {
            uint amount = balanceOf[msg.sender];
            balanceOf[msg.sender] = 0;
            if (amount > 0) {
                if (msg.sender.send(amount)) {
                    FundTransfer(msg.sender, amount, false);
                } else {
                    balanceOf[msg.sender] = amount;
                }
            }
        }

        if (fundingGoalReached && beneficiary == msg.sender) {
            if (beneficiary.send(amountRaised)) {
                FundTransfer(beneficiary, amountRaised, false);
            } else {
                //If we fail to send the funds to beneficiary, unlock funders balance
                fundingGoalReached = false;
            }
        }
    }
}

error: pathspec 'OrphanToken.sol' did not match any file(s) known to git


Vlad helped

Vlad helped

pragma solidity ^0.4.4;
contract News {

    struct Content {
        address owner;
        uint price;
    }

    struct Order {
        address buyer;
    }

    mapping(bytes => Content) contents;
    mapping(bytes => Order) orders;

    address contractMaker;

    function News() {
        contractMaker = msg.sender;
    }

    function add(bytes fingerprint, uint price) {
        Content content = contents[fingerprint];
        content.owner = msg.sender;
        content.price = price;
    }

    function getPrice(bytes fingerprint) returns(uint _price){
        Content content = contents[fingerprint];
        return (content.price);
    }

    function buy(bytes fingerprint) payable {
        Content content = contents[fingerprint];
        Order order = orders[fingerprint];
        if (msg.value < content.price) {
          revert();
        } else {
            order.buyer = msg.sender;
            content.owner.transfer(msg.value);
        }
    }

    function proveBuy(bytes fingerprint) public constant returns (bool){
        Order order = orders[fingerprint];
        if(order.buyer == msg.sender){
            return true;
        }
    }

    function proveOwnership(bytes fingerprint) public constant returns (bool){
        Content content = contents[fingerprint];
        if(content.owner == msg.sender){
            return true;
        }
    }
}

pragma solidity ^0.4.4;
contract News {

    struct Content {
        address owner;
        uint price;
    }

    struct Order {
        address buyer;
    }

    mapping(uint => Content) contents;
    mapping(uint => Order) orders;
    //Order[] orders;

    address contractMaker;

    function News() {
        contractMaker = msg.sender;
    }

    function add(uint256 fingerprint, uint price) {
        Content content = contents[fingerprint];
        content.owner = msg.sender;
        content.price = price;
    }

    function getPrice(uint256 fingerprint) returns(uint _price){
        Content content = contents[fingerprint];
        return (content.price);
    }

    function buy(uint256 fingerprint) payable {
        Content content = contents[fingerprint];
        Order order = orders[fingerprint];
        if (msg.value < content.price) {
          revert();
        } else {
            order.buyer = msg.sender;
            content.owner.transfer(msg.value);
        }
    }

    function proveBuy(uint256 fingerprint) public constant returns (bool){
        Order order = orders[fingerprint];
        if(order.buyer == msg.sender){
            return true;
        }
    }

    function proveOwnership(uint256 fingerprint) public constant returns (bool){
        Content content = contents[fingerprint];
        if(content.owner == msg.sender){
            return true;
        }
    }
}


Added getters for testing

Added getters for testing

pragma solidity ^0.4.0;
contract ItemTracking {

    struct Item {
        uint id;
        address owner;
        uint[] components;
        bool exists;
        bool created;
    }

    mapping(uint => Item) items;

    modifier itemCreated(uint id) {
        if (items[id].created == false) {
            throw;
        }
        _;
    }

    modifier itemNotCreated(uint id) {
        if (items[id].created) {
            throw;
        }
        _;
    }

    modifier itemExists(uint id) {
        if (items[id].exists == false) {
            throw;
        }
        _;
    }

    modifier itemsExist(uint[] ids) {
        for (uint i = 0; i < ids.length; i++) {
            if (items[ids[i]].exists == false) {
                throw;
            }
        }
        _;
    }

    modifier itemOwnedBySender(uint id) {
        if (items[id].owner != msg.sender) {
            throw;
        }
        _;
    }

    modifier itemsOwnedBySender(uint[] ids) {
        for (uint i = 0; i < ids.length; i++) {
            if (items[ids[i]].owner != msg.sender) {
                throw;
            }
        }
        _;
    }

    modifier itemIsCombined(uint id) {
        if (items[id].components.length < 2) {
            throw;
        }
        _;
    }

    modifier itemContainsComponents(uint id, uint[] componentIds) {

        for (uint i = 0; i < componentIds.length; i++) {
            bool componentFound = false;

            for (uint j = 0; j < items[id].components.length; j++) {
                if (items[id].components[j] == componentIds[i]) {
                    componentFound = true;
                    break;
                }
            }

            if (!componentFound) {
                throw;
            }
        }
        _;
    }

    // Create a new item
    function create(uint id)
    itemNotCreated(id) {
        items[id].id = id;
        items[id].exists = true;
        items[id].created = true;
        items[id].owner = msg.sender;
    }

    // Combine items to create a single new one
    function combine(uint[] srcIds, uint resultId)
    itemsExist(srcIds)
    itemsOwnedBySender(srcIds) {
        // Verify that at least 2 components are being combined
        if (srcIds.length < 2) {
            throw;
        }

        for (uint i = 0; i < srcIds.length; i++) {
            items[srcIds[i]].exists = false;
        }
        create(resultId);
        items[resultId].components = srcIds;
    }

    // Split a combined item into its components
    function split(uint srcId)
    itemExists(srcId)
    itemOwnedBySender(srcId)
    itemIsCombined(srcId) {
        items[srcId].exists = false;
        for (uint i = 0; i < items[srcId].components.length; i++) {
            uint componentId = items[srcId].components[i];
            items[componentId].exists = true;
            items[componentId].owner = items[srcId].owner;
        }
    }

    // Extract the sub-components listed in the parameter. Leave the rest of the
    // components in the parent item. Parent item maintains its old ID.
    // If less than 2 components would remain in the parent component, then
    // extract behaves exactly like split.
    function extract(uint srcId, uint[] toBeExtractedIds)
    itemExists(srcId)
    itemOwnedBySender(srcId)
    itemIsCombined(srcId)
    itemContainsComponents(srcId, toBeExtractedIds) {
        // If less than 2 components would remain in the parent item after
        // the extraction, perform split.
        if (items[srcId].components.length - toBeExtractedIds.length < 2) {
            split(srcId);
            return;
        }

        // Make extracted components exist and grant ownership to owner of
        // parent item.
        for (uint i = 0; i < toBeExtractedIds.length; i++) {
            uint componentId = toBeExtractedIds[i];
            items[componentId].exists = true;
            items[componentId].owner = items[srcId].owner;
        }

        // Remove extracted components from parent item's component listing
        for (uint i = 0; i < toBeExtractedIds.length; i++) {

            // Find out what the components index is in parent item's component
            // listing.
            uint componentIndex = 0;
            for (uint j = 0; j < items[srcId].components.length; j++) {
                if (componentId == items[srcId].components[j]) {
                    componentIndex = j;
                    break;
                }
            }

            // Remove item from componentIndex. To not bloat the array, let's do
            // this by copying value from the last index to componentIndex and
            // then remove the last index.
            uint lastIndex = items[srcId].components.length - 1;
            items[srcId].components[componentIndex] = items[srcId].components[lastIndex]
            delete items[srcId].components[lastIndex];
            items[srcId].components.length--;
        }
    }

    // Handover ownership of the item
    function handover(uint id, address receiver)
    itemExists(id)
    itemOwnedBySender(id) {
        items[id].owner = receiver;
    }

    // Return number of components for a given item
    function getComponentCount(uint id) itemCreated(id) returns (uint) {
        return items[srcId].components.length;
    }

    // Return ID of a component of a given parent item at given index.
    function getComponentId(uint parentId, uint componentIndex)
    itemCreated(parentId)
    itemIsCombined(parentId)
    returns (uint) {
        if (componentIndex >= items[parentId].components.length) {
            throw;
        }
        return items[parentId].components[componentIndex];
    }

    // Return owner of a given item
    function getOwner(uint id) itemCreated(id) returns (address) {
        return items[id].owner;
    }

    // Return exists status of a given item
    function getExistsStatus(uint id) itemCreated(id) returns (bool) {
        return items[id].exists;
    }

    // Return created status of a given item
    function getCreatedStatus(uint id) returns (bool) {
        return items[id].created;
    }

}

pragma solidity ^0.4.0;
contract ItemTracking {

    struct Item {
        uint id;
        address owner;
        uint[] components;
        bool exists;
        bool created;
    }

    mapping(uint => Item) items;

    modifier itemNotCreated(uint id) {
        if (items[id].created) {
            throw;
        }
        _;
    }

    modifier itemExists(uint id) {
        if (items[id].exists == false) {
            throw;
        }
        _;
    }

    modifier itemsExist(uint[] ids) {
        for (uint i = 0; i < ids.length; i++) {
            if (items[ids[i]].exists == false) {
                throw;
            }
        }
        _;
    }

    modifier itemOwnedBySender(uint id) {
        if (items[id].owner != msg.sender) {
            throw;
        }
        _;
    }

    modifier itemsOwnedBySender(uint[] ids) {
        for (uint i = 0; i < ids.length; i++) {
            if (items[ids[i]].owner != msg.sender) {
                throw;
            }
        }
        _;
    }

    modifier itemIsCombined(uint id) {
        if (items[id].components.length < 2) {
            throw;
        }
        _;
    }

    modifier itemContainsComponents(uint id, uint[] componentIds) {

        for (uint i = 0; i < componentIds.length; i++) {
            bool componentFound = false;

            for (uint j = 0; j < items[id].components.length; j++) {
                if (items[id].components[j] == componentIds[i]) {
                    componentFound = true;
                    break;
                }
            }

            if (!componentFound) {
                throw;
            }
        }
        _;
    }

    // Create a new item
    function create(uint id)
    itemNotCreated(id) {
        items[id].id = id;
        items[id].exists = true;
        items[id].created = true;
        items[id].owner = msg.sender;
    }

    // Combine items to create a single new one
    function combine(uint[] srcIds, uint resultId)
    itemsExist(srcIds)
    itemsOwnedBySender(srcIds) {
        // Verify that at least 2 components are being combined
        if (srcIds.length < 2) {
            throw;
        }

        for (uint i = 0; i < srcIds.length; i++) {
            items[srcIds[i]].exists = false;
        }
        create(resultId);
        items[resultId].components = srcIds;
    }

    // Split a combined item into its components
    function split(uint srcId)
    itemExists(srcId)
    itemOwnedBySender(srcId)
    itemIsCombined(srcId) {
        items[srcId].exists = false;
        for (uint i = 0; i < items[srcId].components.length; i++) {
            uint componentId = items[srcId].components[i];
            items[componentId].exists = true;
            items[componentId].owner = items[srcId].owner;
        }
    }

    // Extract the sub-components listed in the parameter. Leave the rest of the
    // components in the parent item. Parent item maintains its old ID.
    // If less than 2 components would remain in the parent component, then
    // extract behaves exactly like split.
    function extract(uint srcId, uint[] toBeExtractedIds)
    itemExists(srcId)
    itemOwnedBySender(srcId)
    itemIsCombined(srcId)
    itemContainsComponents(srcId, toBeExtractedIds) {
        // If less than 2 components would remain in the parent item after
        // the extraction, perform split.
        if (items[srcId].components.length - toBeExtractedIds.length < 2) {
            split(srcId);
            return;
        }

        // Make extracted components exist and grant ownership to owner of
        // parent item.
        for (uint i = 0; i < toBeExtractedIds.length; i++) {
            uint componentId = toBeExtractedIds[i];
            items[componentId].exists = true;
            items[componentId].owner = items[srcId].owner;
        }

        // Remove extracted components from parent item's component listing
        for (uint i = 0; i < toBeExtractedIds.length; i++) {

            // Find out what the components index is in parent item's component
            // listing.
            uint componentIndex = 0;
            for (uint j = 0; j < items[srcId].components.length; j++) {
                if (componentId == items[srcId].components[j]) {
                    componentIndex = j;
                    break;
                }
            }

            // Remove item from componentIndex. To not bloat the array, let's do
            // this by copying value from the last index to componentIndex and
            // then remove the last index.
            uint lastIndex = items[srcId].components.length - 1;
            items[srcId].components[componentIndex] = items[srcId].components[lastIndex]
            delete items[srcId].components[lastIndex];
            items[srcId].components.length--;
        }
    }

    // Handover ownership of the item
    function handover(uint id, address receiver)
    itemExists(id)
    itemOwnedBySender(id) {
        items[id].owner = receiver;
    }
}


Fix mload8 emulation in signatureSplit

Fix mload8 emulation in signatureSplit

Ran across this while reviewing the netting code.

To grab the lower 8 bits should be `(x & 0xff)`, not `(x & 0x01)`. For
`v` in `[0, 1]` (old versions of geth) this should cause an issue but
for `v` in `[27, 28]` (everything else), the value of v will be reversed
(the resulting value of `v` will be `(27 & 1) + 27 == 28`, or `(28 & 1)
 + 27 == 27`).

pragma solidity ^0.4.0;

import "./Token.sol";

library NettingChannelLibrary {
    struct Participant
    {
        address node_address;

        // Total amount of token transferred to this smart contract through the
        // `deposit` function, note that direct token transfer cannot be
        // tracked and will be burned.
        uint256 balance;

        // The latest known merkle root of the pending hash-time locks, used to
        // validate the withdrawn proofs.
        bytes32 locksroot;

        // The latest known transferred_amount from this node to the other
        // participant, used to compute the net balance on settlement.
        uint256 transferred_amount;

        // Value used to order transfers and only accept the latest on calls to
        // update, this will only be relevant after either #182 or #293 is
        // implemented.
        uint64 nonce;

        // A mapping to keep track of locks that have been withdrawn.
        mapping(bytes32 => bool) withdrawn_locks;
    }

    struct Data {
        uint settle_timeout;
        uint opened;
        uint closed;
        uint settled;
        address closing_address;
        Token token;
        Participant[2] participants;
        mapping(address => uint8) participant_index;
        bool updated;
    }

    modifier notSettledButClosed(Data storage self) {
        require(self.settled <= 0 && self.closed > 0);
        _;
    }

    modifier stillTimeout(Data storage self) {
        require(self.closed + self.settle_timeout >= block.number);
        _;
    }

    modifier timeoutOver(Data storage self) {
        require(self.closed + self.settle_timeout <= block.number);
        _;
    }

    modifier channelSettled(Data storage self) {
        require(self.settled != 0);
        _;
    }

    function isValidNonce(Data storage self, uint64 nonce)
        private
        returns (bool)
    {
        return (
            nonce >= self.opened * (2 ** 32) &&
            nonce < (self.opened + 1) * (2 ** 32)
        );
    }

    /// @notice Deposit amount to channel.
    /// @dev Deposit an amount to the channel. At least one of the participants
    /// must deposit before the channel is opened.
    /// @param amount The amount to be deposited to the address
    /// @return Success if the transfer was successful
    /// @return The new balance of the invoker
    function deposit(Data storage self, uint256 amount)
        returns (bool success, uint256 balance)
    {
        uint8 index;

        require(self.opened > 0);
        require(self.closed == 0);

        if (self.token.balanceOf(msg.sender) < amount) {
            throw;
        }

        index = index_or_throw(self, msg.sender);
        Participant storage participant = self.participants[index];

        success = self.token.transferFrom(msg.sender, this, amount);
        if (success == true) {
            balance = participant.balance;
            balance += amount;
            participant.balance = balance;

            return (true, balance);
        }

        return (false, 0);
    }

    /// @notice Close a channel between two parties that was used bidirectionally
    /// @param their_transfer The latest known transfer of the other participant
    ///                       to the channel. Can also be empty, in which case
    ///                       we are attempting to close a channel without any
    ///                       transfers.
    function close(Data storage self, bytes their_transfer)
    {
        uint closer_index;
        uint counterparty_index;
        bytes memory transfer_raw;
        uint64 nonce;
        address transfer_address;
        address recipient;
        bytes32 locksroot;
        uint256 transferred_amount;

        // close can be called only once
        if (self.closed > 0) {
            throw;
        }

        // Only a participant can call close
        closer_index = index_or_throw(self, msg.sender);

        self.closing_address = msg.sender;
        self.closed = block.number;

        // Only the closing party can provide a transfer from the counterparty,
        // and only when this function is called, i.e. this value can not be
        // updated afterwards.

        // An empty value means that the closer never received a transfer, or
        // he is intentionally not providing the latest transfer, in which case
        // the closing party is going to lose the tokens that were transferred
        // to him.
        if (their_transfer.length != 0) {
            (transfer_raw, transfer_address) = getTransferRawAddress(their_transfer);
            counterparty_index = index_or_throw(self, transfer_address);

            // only a message from the counter party is valid
            if (closer_index == counterparty_index) {
                throw;
            }

            // update the structure of the counterparty with its data provided
            // by the closing node
            Participant storage counterparty = self.participants[counterparty_index];

            (nonce, recipient, locksroot, transferred_amount) = decodeTransfer(transfer_raw);

            // only accept messages with a valid nonce
            if (!isValidNonce(self, nonce)) {
                throw;
            }

            // the registered message recipient should be the closing party
            require(recipient == self.closing_address);

            counterparty.nonce = nonce;
            counterparty.locksroot = locksroot;
            counterparty.transferred_amount = transferred_amount;
        }

    }

    /// @notice Updates counter party transfer after closing.
    /// @param their_transfer The transfer the counterparty believes is the
    ///                       valid state for the first participant.
    function updateTransfer(Data storage self, bytes their_transfer)
        notSettledButClosed(self)
        stillTimeout(self)
    {
        address transfer_address;
        address recipient;
        bytes32 locksroot;
        bytes memory transfer_raw;
        uint256 transferred_amount;
        uint64 nonce;
        uint8 caller_index;
        uint8 closer_index;

        // updateTransfer can be called by the counter party only once
        if (self.updated) {
            throw;
        }
        self.updated = true;

        // Only a participant can call updateTransfer (#293 for third parties)
        caller_index = index_or_throw(self, msg.sender);

        // The closer is not allowed to call updateTransfer
        if (self.closing_address == msg.sender) {
            throw;
        }

        (transfer_raw, transfer_address) = getTransferRawAddress(their_transfer);

        // Counter party can only update the closer transfer
        if (transfer_address != self.closing_address) {
            throw;
        }

        // Update the structure of the closer with its data provided by the
        // counterparty
        closer_index = 1 - caller_index;

        (nonce, recipient, locksroot, transferred_amount) = decodeTransfer(transfer_raw);

        // only accept messages with a valid nonce
        if (!isValidNonce(self, nonce)) {
            throw;
        }

        // the registered recipient in the message should be us
        // Note: could have taken msg.sender here but trying to be future-proof
        // for when we allow third party updates
        Participant storage updating_party = self.participants[caller_index];
        require(updating_party.node_address == recipient);

        self.participants[closer_index].nonce = nonce;
        self.participants[closer_index].locksroot = locksroot;
        self.participants[closer_index].transferred_amount = transferred_amount;
    }

    /// @notice Unlock a locked transfer
    /// @dev Unlock a locked transfer
    /// @param locked_encoded The lock
    /// @param merkle_proof The merkle proof
    /// @param secret The secret
    function withdraw(Data storage self, bytes locked_encoded, bytes merkle_proof, bytes32 secret)
        notSettledButClosed(self)
    {
        uint amount;
        uint8 index;
        uint64 expiration;
        bytes32 h;
        bytes32 hashlock;

        // Check if msg.sender is a participant and select the partner (for
        // third party unlock see #541)
        index = 1 - index_or_throw(self, msg.sender);
        Participant storage counterparty = self.participants[index];

        // An empty locksroot means there are no pending locks
        if (counterparty.locksroot == 0) {
            throw;
        }

        (expiration, amount, hashlock) = decodeLock(locked_encoded);

        // A lock can be withdrawn only once per participant
        if (counterparty.withdrawn_locks[hashlock]) {
            throw;
        }
        counterparty.withdrawn_locks[hashlock] = true;

        require(expiration >= block.number);

        if (hashlock != sha3(secret)) {
            throw;
        }

        h = computeMerkleRoot(locked_encoded, merkle_proof);

        require(counterparty.locksroot == h);

        // This implementation allows for each transfer to be set only once, so
        // it's safe to update the transferred_amount in place.
        //
        // Once third parties are allowed to update the counter party transfer
        // (#293, #182) the locksroot may change, if the locksroot change the
        // transferred_amount must be reset and locks must be re-withdrawn, so
        // this is also safe.
        //
        // This may be problematic if an update changes the transferred_amount
        // but not the locksroot, since the locks don't need to be
        // re-withdrawn, the difference in the transferred_amount must be
        // accounted for.
        counterparty.transferred_amount += amount;
    }

    function computeMerkleRoot(bytes lock, bytes merkle_proof)
        internal
        constant
        returns (bytes32)
    {
        require(merkle_proof.length % 32 == 0);

        uint i;
        bytes32 h;
        bytes32 el;

        h = sha3(lock);
        for (i = 32; i <= merkle_proof.length; i += 32) {
            assembly {
                el := mload(add(merkle_proof, i))
            }

            if (h < el) {
                h = sha3(h, el);
            } else {
                h = sha3(el, h);
            }
        }

        return h;
    }

    /// @notice Settles the balance between the two parties
    /// @dev Settles the balances of the two parties fo the channel
    /// @return The participants with netted balances
    function settle(Data storage self)
        notSettledButClosed(self)
        timeoutOver(self)
    {
        uint8 closing_index;
        uint8 counter_index;
        uint256 total_deposit;
        uint256 counter_net;
        uint256 closer_amount;
        uint256 counter_amount;

        self.settled = block.number;

        closing_index = index_or_throw(self, self.closing_address);
        counter_index = 1 - closing_index;

        Participant storage closing_party = self.participants[closing_index];
        Participant storage counter_party = self.participants[counter_index];

        counter_net = (
            counter_party.balance
            + closing_party.transferred_amount
            - counter_party.transferred_amount
        );

        // Direct token transfers done through the token `transfer` function
        // cannot be accounted for, these superfluous tokens will be burned,
        // this is because there is no way to tell which participant (if any)
        // had ownership over the token.
        total_deposit = closing_party.balance + counter_party.balance;

        // When the closing party does not provide the counter party transfer,
        // the `counter_net` may be larger than the `total_deposit`, without
        // the min the token transfer fail and the token is locked.
        counter_amount = min(counter_net, total_deposit);

        // When the counter party does not provide the closing party transfer,
        // then `counter_amount` may be negative and the transfer fails, force
        // the value to 0.
        counter_amount = max(counter_amount, 0);

        // At this point `counter_amount` is between [0,total_deposit], so this
        // is safe.
        closer_amount = total_deposit - counter_amount;

        if (counter_amount > 0) {
            if (!self.token.transfer(counter_party.node_address, counter_amount)) {
                throw;
            }
        }

        if (closer_amount > 0) {
            if (!self.token.transfer(closing_party.node_address, closer_amount)) {
                throw;
            }
        }

        kill(self);
    }

    function getTransferRawAddress(bytes memory signed_transfer) internal returns (bytes memory, address) {
        uint signature_start;
        uint length;
        bytes memory signature;
        bytes memory transfer_raw;
        bytes32 transfer_hash;
        address transfer_address;

        length = signed_transfer.length;
        signature_start = length - 65;
        signature = slice(signed_transfer, signature_start, length);
        transfer_raw = slice(signed_transfer, 0, signature_start);

        transfer_hash = sha3(transfer_raw);
        var (r, s, v) = signatureSplit(signature);
        transfer_address = ecrecover(transfer_hash, v, r, s);

        return (transfer_raw, transfer_address);
    }

    // NOTES:
    //
    // - The EVM is a big-endian, byte addressing machine, with 32bytes/256bits
    //   words.
    // - The Ethereum Contract ABI specifies that variable length types have a
    //   32bytes prefix to define the variable size.
    // - Solidity has additional data types that are narrower than 32bytes
    //   (e.g. uint128 uses a half word).
    // - Solidity uses the *least-significant* bits of the word to store the
    //   values of a narrower type.
    //
    // GENERAL APPROACH:
    //
    // Add to the message pointer the number of bytes required to move the
    // address so that the target data is at the end of the 32bytes word.
    //
    // EXAMPLE:
    //
    // To decode the cmdid, consider this initial state:
    //
    //
    //     v- pointer word start
    //     [ 32 bytes length prefix ][ cmdid ] ----
    //                              ^- pointer word end
    //
    //
    // Because the cmdid has 1 byte length the type uint8 is used, the decoder
    // needs to move the pointer so the cmdid is at the end of the pointer
    // word.
    //
    //
    //             v- pointer word start [moved 1byte ahead]
    //     [ 32 bytes length prefix ][ cmdid ] ----
    //                                       ^- pointer word end
    //
    //
    // Now the data of the cmdid can be loaded to the uint8 variable.
    //
    // REFERENCES:
    // - https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
    // - http://solidity.readthedocs.io/en/develop/assembly.html

    function decodeTransfer(bytes transfer_raw)
        internal
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        uint cmdid = uint(transfer_raw[0]);

        if (cmdid == 5) {
            return decodeDirectTransfer(transfer_raw);
        } else if (cmdid == 7) {
            return decodeMediatedTransfer(transfer_raw);
        } else if (cmdid == 8) {
            return decodeRefundTransfer(transfer_raw);
        }

        throw;
    }

    function decodeDirectTransfer(bytes memory message)
        private
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        // size of the raw message without the signature
        if (message.length != 124) {
            throw;
        }

        // Message format:
        // [0:1] cmdid
        // [1:4] pad
        // [4:12] nonce
        // [12:20] identifier
        // [20:40] token
        // [40:60] recipient
        // [60:92] transferred_amount
        // [92:124] optional_locksroot
        assembly {
            nonce := mload(add(message, 12))
            recipient := mload(add(message, 60))
            transferred_amount := mload(add(message, 92))
            locksroot := mload(add(message, 124))
        }
    }

    function decodeMediatedTransfer(bytes memory message)
        private
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        // size of the raw message without the signature
        require(message.length == 268);

        // Message format:
        // [0:1] cmdid
        // [1:4] pad
        // [4:12] nonce
        // [12:20] identifier
        // [20:28] expiration
        // [28:48] token
        // [48:68] recipient
        // [68:88] target
        // [88:108] initiator
        // [108:140] locksroot
        // [140:172] hashlock
        // [172:204] transferred_amoun
        // [204:236] amount
        // [236:268] fee
        assembly {
            nonce := mload(add(message, 12))
            recipient := mload(add(message, 68))
            locksroot := mload(add(message, 140))
            transferred_amount := mload(add(message, 204))
        }
    }

    function decodeRefundTransfer(bytes memory message)
        private
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        // size of the raw message without the signature
        require(message.length == 196);

        // Message format:
        // [0:1] cmdid
        // [1:4] pad
        // [4:12] nonce
        // [12:20] identifier
        // [20:28] expiration
        // [28:48] token
        // [48:68] recipient
        // [68:100] locksroot
        // [100:132] transferred_amount
        // [132:164] amount
        // [164:196] hashlock
        assembly {
            nonce := mload(add(message, 12))
            recipient := mload(add(message, 68))
            locksroot := mload(add(message, 100))
            transferred_amount := mload(add(message, 132))
        }
    }

    function decodeLock(bytes lock) internal returns (uint64 expiration, uint amount, bytes32 hashlock) {
        if (lock.length != 72) {
            throw;
        }

        // Lock format:
        // [0:8] expiration
        // [8:40] amount
        // [40:72] hashlock
        assembly {
            expiration := mload(add(lock, 8))
            amount := mload(add(lock, 40))
            hashlock := mload(add(lock, 72))
        }
    }

    function signatureSplit(bytes signature) private returns (bytes32 r, bytes32 s, uint8 v) {
        // The signature format is a compact form of:
        //   {bytes32 r}{bytes32 s}{uint8 v}
        // Compact means, uint8 is not padded to 32 bytes.
        assembly {
            r := mload(add(signature, 32))
            s := mload(add(signature, 64))
            // Here we are loading the last 32 bytes, including 31 bytes
            // of 's'. There is no 'mload8' to do this.
            //
            // 'byte' is not working due to the Solidity parser, so lets
            // use the second best option, 'and'
            v := and(mload(add(signature, 65)), 0xff)
        }
        // old geth sends a `v` value of [0,1], while the new, in line with the YP sends [27,28]
        if(v < 27) v += 27;
    }

    function slice(bytes a, uint start, uint end) private returns (bytes n) {
        if (a.length < end) {
            throw;
        }
        if (start < 0) {
            throw;
        }

        n = new bytes(end - start);
        for (uint i = start; i < end; i++) { //python style slice
            n[i - start] = a[i];
        }
    }

    function index_or_throw(Data storage self, address participant_address) private returns (uint8) {
        uint8 n;
        // Return index of participant, or throw
        n = self.participant_index[participant_address];
        if (n == 0) {
            throw;
        }
        return n - 1;
    }

    function min(uint a, uint b) constant internal returns (uint) {
        return a > b ? b : a;
    }

    function max(uint a, uint b) constant internal returns (uint) {
        return a > b ? a : b;
    }

    function kill(Data storage self) channelSettled(self) {
        selfdestruct(0x00000000000000000000);
    }
}

pragma solidity ^0.4.0;

import "./Token.sol";

library NettingChannelLibrary {
    struct Participant
    {
        address node_address;

        // Total amount of token transferred to this smart contract through the
        // `deposit` function, note that direct token transfer cannot be
        // tracked and will be burned.
        uint256 balance;

        // The latest known merkle root of the pending hash-time locks, used to
        // validate the withdrawn proofs.
        bytes32 locksroot;

        // The latest known transferred_amount from this node to the other
        // participant, used to compute the net balance on settlement.
        uint256 transferred_amount;

        // Value used to order transfers and only accept the latest on calls to
        // update, this will only be relevant after either #182 or #293 is
        // implemented.
        uint64 nonce;

        // A mapping to keep track of locks that have been withdrawn.
        mapping(bytes32 => bool) withdrawn_locks;
    }

    struct Data {
        uint settle_timeout;
        uint opened;
        uint closed;
        uint settled;
        address closing_address;
        Token token;
        Participant[2] participants;
        mapping(address => uint8) participant_index;
        bool updated;
    }

    modifier notSettledButClosed(Data storage self) {
        require(self.settled <= 0 && self.closed > 0);
        _;
    }

    modifier stillTimeout(Data storage self) {
        require(self.closed + self.settle_timeout >= block.number);
        _;
    }

    modifier timeoutOver(Data storage self) {
        require(self.closed + self.settle_timeout <= block.number);
        _;
    }

    modifier channelSettled(Data storage self) {
        require(self.settled != 0);
        _;
    }

    function isValidNonce(Data storage self, uint64 nonce)
        private
        returns (bool)
    {
        return (
            nonce >= self.opened * (2 ** 32) &&
            nonce < (self.opened + 1) * (2 ** 32)
        );
    }

    /// @notice Deposit amount to channel.
    /// @dev Deposit an amount to the channel. At least one of the participants
    /// must deposit before the channel is opened.
    /// @param amount The amount to be deposited to the address
    /// @return Success if the transfer was successful
    /// @return The new balance of the invoker
    function deposit(Data storage self, uint256 amount)
        returns (bool success, uint256 balance)
    {
        uint8 index;

        require(self.opened > 0);
        require(self.closed == 0);

        if (self.token.balanceOf(msg.sender) < amount) {
            throw;
        }

        index = index_or_throw(self, msg.sender);
        Participant storage participant = self.participants[index];

        success = self.token.transferFrom(msg.sender, this, amount);
        if (success == true) {
            balance = participant.balance;
            balance += amount;
            participant.balance = balance;

            return (true, balance);
        }

        return (false, 0);
    }

    /// @notice Close a channel between two parties that was used bidirectionally
    /// @param their_transfer The latest known transfer of the other participant
    ///                       to the channel. Can also be empty, in which case
    ///                       we are attempting to close a channel without any
    ///                       transfers.
    function close(Data storage self, bytes their_transfer)
    {
        uint closer_index;
        uint counterparty_index;
        bytes memory transfer_raw;
        uint64 nonce;
        address transfer_address;
        address recipient;
        bytes32 locksroot;
        uint256 transferred_amount;

        // close can be called only once
        if (self.closed > 0) {
            throw;
        }

        // Only a participant can call close
        closer_index = index_or_throw(self, msg.sender);

        self.closing_address = msg.sender;
        self.closed = block.number;

        // Only the closing party can provide a transfer from the counterparty,
        // and only when this function is called, i.e. this value can not be
        // updated afterwards.

        // An empty value means that the closer never received a transfer, or
        // he is intentionally not providing the latest transfer, in which case
        // the closing party is going to lose the tokens that were transferred
        // to him.
        if (their_transfer.length != 0) {
            (transfer_raw, transfer_address) = getTransferRawAddress(their_transfer);
            counterparty_index = index_or_throw(self, transfer_address);

            // only a message from the counter party is valid
            if (closer_index == counterparty_index) {
                throw;
            }

            // update the structure of the counterparty with its data provided
            // by the closing node
            Participant storage counterparty = self.participants[counterparty_index];

            (nonce, recipient, locksroot, transferred_amount) = decodeTransfer(transfer_raw);

            // only accept messages with a valid nonce
            if (!isValidNonce(self, nonce)) {
                throw;
            }

            // the registered message recipient should be the closing party
            require(recipient == self.closing_address);

            counterparty.nonce = nonce;
            counterparty.locksroot = locksroot;
            counterparty.transferred_amount = transferred_amount;
        }

    }

    /// @notice Updates counter party transfer after closing.
    /// @param their_transfer The transfer the counterparty believes is the
    ///                       valid state for the first participant.
    function updateTransfer(Data storage self, bytes their_transfer)
        notSettledButClosed(self)
        stillTimeout(self)
    {
        address transfer_address;
        address recipient;
        bytes32 locksroot;
        bytes memory transfer_raw;
        uint256 transferred_amount;
        uint64 nonce;
        uint8 caller_index;
        uint8 closer_index;

        // updateTransfer can be called by the counter party only once
        if (self.updated) {
            throw;
        }
        self.updated = true;

        // Only a participant can call updateTransfer (#293 for third parties)
        caller_index = index_or_throw(self, msg.sender);

        // The closer is not allowed to call updateTransfer
        if (self.closing_address == msg.sender) {
            throw;
        }

        (transfer_raw, transfer_address) = getTransferRawAddress(their_transfer);

        // Counter party can only update the closer transfer
        if (transfer_address != self.closing_address) {
            throw;
        }

        // Update the structure of the closer with its data provided by the
        // counterparty
        closer_index = 1 - caller_index;

        (nonce, recipient, locksroot, transferred_amount) = decodeTransfer(transfer_raw);

        // only accept messages with a valid nonce
        if (!isValidNonce(self, nonce)) {
            throw;
        }

        // the registered recipient in the message should be us
        // Note: could have taken msg.sender here but trying to be future-proof
        // for when we allow third party updates
        Participant storage updating_party = self.participants[caller_index];
        require(updating_party.node_address == recipient);

        self.participants[closer_index].nonce = nonce;
        self.participants[closer_index].locksroot = locksroot;
        self.participants[closer_index].transferred_amount = transferred_amount;
    }

    /// @notice Unlock a locked transfer
    /// @dev Unlock a locked transfer
    /// @param locked_encoded The lock
    /// @param merkle_proof The merkle proof
    /// @param secret The secret
    function withdraw(Data storage self, bytes locked_encoded, bytes merkle_proof, bytes32 secret)
        notSettledButClosed(self)
    {
        uint amount;
        uint8 index;
        uint64 expiration;
        bytes32 h;
        bytes32 hashlock;

        // Check if msg.sender is a participant and select the partner (for
        // third party unlock see #541)
        index = 1 - index_or_throw(self, msg.sender);
        Participant storage counterparty = self.participants[index];

        // An empty locksroot means there are no pending locks
        if (counterparty.locksroot == 0) {
            throw;
        }

        (expiration, amount, hashlock) = decodeLock(locked_encoded);

        // A lock can be withdrawn only once per participant
        if (counterparty.withdrawn_locks[hashlock]) {
            throw;
        }
        counterparty.withdrawn_locks[hashlock] = true;

        require(expiration >= block.number);

        if (hashlock != sha3(secret)) {
            throw;
        }

        h = computeMerkleRoot(locked_encoded, merkle_proof);

        require(counterparty.locksroot == h);

        // This implementation allows for each transfer to be set only once, so
        // it's safe to update the transferred_amount in place.
        //
        // Once third parties are allowed to update the counter party transfer
        // (#293, #182) the locksroot may change, if the locksroot change the
        // transferred_amount must be reset and locks must be re-withdrawn, so
        // this is also safe.
        //
        // This may be problematic if an update changes the transferred_amount
        // but not the locksroot, since the locks don't need to be
        // re-withdrawn, the difference in the transferred_amount must be
        // accounted for.
        counterparty.transferred_amount += amount;
    }

    function computeMerkleRoot(bytes lock, bytes merkle_proof)
        internal
        constant
        returns (bytes32)
    {
        require(merkle_proof.length % 32 == 0);

        uint i;
        bytes32 h;
        bytes32 el;

        h = sha3(lock);
        for (i = 32; i <= merkle_proof.length; i += 32) {
            assembly {
                el := mload(add(merkle_proof, i))
            }

            if (h < el) {
                h = sha3(h, el);
            } else {
                h = sha3(el, h);
            }
        }

        return h;
    }

    /// @notice Settles the balance between the two parties
    /// @dev Settles the balances of the two parties fo the channel
    /// @return The participants with netted balances
    function settle(Data storage self)
        notSettledButClosed(self)
        timeoutOver(self)
    {
        uint8 closing_index;
        uint8 counter_index;
        uint256 total_deposit;
        uint256 counter_net;
        uint256 closer_amount;
        uint256 counter_amount;

        self.settled = block.number;

        closing_index = index_or_throw(self, self.closing_address);
        counter_index = 1 - closing_index;

        Participant storage closing_party = self.participants[closing_index];
        Participant storage counter_party = self.participants[counter_index];

        counter_net = (
            counter_party.balance
            + closing_party.transferred_amount
            - counter_party.transferred_amount
        );

        // Direct token transfers done through the token `transfer` function
        // cannot be accounted for, these superfluous tokens will be burned,
        // this is because there is no way to tell which participant (if any)
        // had ownership over the token.
        total_deposit = closing_party.balance + counter_party.balance;

        // When the closing party does not provide the counter party transfer,
        // the `counter_net` may be larger than the `total_deposit`, without
        // the min the token transfer fail and the token is locked.
        counter_amount = min(counter_net, total_deposit);

        // When the counter party does not provide the closing party transfer,
        // then `counter_amount` may be negative and the transfer fails, force
        // the value to 0.
        counter_amount = max(counter_amount, 0);

        // At this point `counter_amount` is between [0,total_deposit], so this
        // is safe.
        closer_amount = total_deposit - counter_amount;

        if (counter_amount > 0) {
            if (!self.token.transfer(counter_party.node_address, counter_amount)) {
                throw;
            }
        }

        if (closer_amount > 0) {
            if (!self.token.transfer(closing_party.node_address, closer_amount)) {
                throw;
            }
        }

        kill(self);
    }

    function getTransferRawAddress(bytes memory signed_transfer) internal returns (bytes memory, address) {
        uint signature_start;
        uint length;
        bytes memory signature;
        bytes memory transfer_raw;
        bytes32 transfer_hash;
        address transfer_address;

        length = signed_transfer.length;
        signature_start = length - 65;
        signature = slice(signed_transfer, signature_start, length);
        transfer_raw = slice(signed_transfer, 0, signature_start);

        transfer_hash = sha3(transfer_raw);
        var (r, s, v) = signatureSplit(signature);
        transfer_address = ecrecover(transfer_hash, v, r, s);

        return (transfer_raw, transfer_address);
    }

    // NOTES:
    //
    // - The EVM is a big-endian, byte addressing machine, with 32bytes/256bits
    //   words.
    // - The Ethereum Contract ABI specifies that variable length types have a
    //   32bytes prefix to define the variable size.
    // - Solidity has additional data types that are narrower than 32bytes
    //   (e.g. uint128 uses a half word).
    // - Solidity uses the *least-significant* bits of the word to store the
    //   values of a narrower type.
    //
    // GENERAL APPROACH:
    //
    // Add to the message pointer the number of bytes required to move the
    // address so that the target data is at the end of the 32bytes word.
    //
    // EXAMPLE:
    //
    // To decode the cmdid, consider this initial state:
    //
    //
    //     v- pointer word start
    //     [ 32 bytes length prefix ][ cmdid ] ----
    //                              ^- pointer word end
    //
    //
    // Because the cmdid has 1 byte length the type uint8 is used, the decoder
    // needs to move the pointer so the cmdid is at the end of the pointer
    // word.
    //
    //
    //             v- pointer word start [moved 1byte ahead]
    //     [ 32 bytes length prefix ][ cmdid ] ----
    //                                       ^- pointer word end
    //
    //
    // Now the data of the cmdid can be loaded to the uint8 variable.
    //
    // REFERENCES:
    // - https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
    // - http://solidity.readthedocs.io/en/develop/assembly.html

    function decodeTransfer(bytes transfer_raw)
        internal
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        uint cmdid = uint(transfer_raw[0]);

        if (cmdid == 5) {
            return decodeDirectTransfer(transfer_raw);
        } else if (cmdid == 7) {
            return decodeMediatedTransfer(transfer_raw);
        } else if (cmdid == 8) {
            return decodeRefundTransfer(transfer_raw);
        }

        throw;
    }

    function decodeDirectTransfer(bytes memory message)
        private
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        // size of the raw message without the signature
        if (message.length != 124) {
            throw;
        }

        // Message format:
        // [0:1] cmdid
        // [1:4] pad
        // [4:12] nonce
        // [12:20] identifier
        // [20:40] token
        // [40:60] recipient
        // [60:92] transferred_amount
        // [92:124] optional_locksroot
        assembly {
            nonce := mload(add(message, 12))
            recipient := mload(add(message, 60))
            transferred_amount := mload(add(message, 92))
            locksroot := mload(add(message, 124))
        }
    }

    function decodeMediatedTransfer(bytes memory message)
        private
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        // size of the raw message without the signature
        require(message.length == 268);

        // Message format:
        // [0:1] cmdid
        // [1:4] pad
        // [4:12] nonce
        // [12:20] identifier
        // [20:28] expiration
        // [28:48] token
        // [48:68] recipient
        // [68:88] target
        // [88:108] initiator
        // [108:140] locksroot
        // [140:172] hashlock
        // [172:204] transferred_amoun
        // [204:236] amount
        // [236:268] fee
        assembly {
            nonce := mload(add(message, 12))
            recipient := mload(add(message, 68))
            locksroot := mload(add(message, 140))
            transferred_amount := mload(add(message, 204))
        }
    }

    function decodeRefundTransfer(bytes memory message)
        private
        returns (uint64 nonce, address recipient, bytes32 locksroot, uint256 transferred_amount)
    {
        // size of the raw message without the signature
        require(message.length == 196);

        // Message format:
        // [0:1] cmdid
        // [1:4] pad
        // [4:12] nonce
        // [12:20] identifier
        // [20:28] expiration
        // [28:48] token
        // [48:68] recipient
        // [68:100] locksroot
        // [100:132] transferred_amount
        // [132:164] amount
        // [164:196] hashlock
        assembly {
            nonce := mload(add(message, 12))
            recipient := mload(add(message, 68))
            locksroot := mload(add(message, 100))
            transferred_amount := mload(add(message, 132))
        }
    }

    function decodeLock(bytes lock) internal returns (uint64 expiration, uint amount, bytes32 hashlock) {
        if (lock.length != 72) {
            throw;
        }

        // Lock format:
        // [0:8] expiration
        // [8:40] amount
        // [40:72] hashlock
        assembly {
            expiration := mload(add(lock, 8))
            amount := mload(add(lock, 40))
            hashlock := mload(add(lock, 72))
        }
    }

    function signatureSplit(bytes signature) private returns (bytes32 r, bytes32 s, uint8 v) {
        // The signature format is a compact form of:
        //   {bytes32 r}{bytes32 s}{uint8 v}
        // Compact means, uint8 is not padded to 32 bytes.
        assembly {
            r := mload(add(signature, 32))
            s := mload(add(signature, 64))
            // Here we are loading the last 32 bytes, including 31 bytes
            // of 's'. There is no 'mload8' to do this.
            //
            // 'byte' is not working due to the Solidity parser, so lets
            // use the second best option, 'and'
            v := and(mload(add(signature, 65)), 1)
        }
        // old geth sends a `v` value of [0,1], while the new, in line with the YP sends [27,28]
        if(v < 27) v += 27;
    }

    function slice(bytes a, uint start, uint end) private returns (bytes n) {
        if (a.length < end) {
            throw;
        }
        if (start < 0) {
            throw;
        }

        n = new bytes(end - start);
        for (uint i = start; i < end; i++) { //python style slice
            n[i - start] = a[i];
        }
    }

    function index_or_throw(Data storage self, address participant_address) private returns (uint8) {
        uint8 n;
        // Return index of participant, or throw
        n = self.participant_index[participant_address];
        if (n == 0) {
            throw;
        }
        return n - 1;
    }

    function min(uint a, uint b) constant internal returns (uint) {
        return a > b ? b : a;
    }

    function max(uint a, uint b) constant internal returns (uint) {
        return a > b ? a : b;
    }

    function kill(Data storage self) channelSettled(self) {
        selfdestruct(0x00000000000000000000);
    }
}


Add paid shares

Add paid shares

/// Partnership
/// Requires all pre-defined partners agreement on transactions and operations.
contract Partnership
{
	event Deposit(address _from, uint _value);
	event ConfirmationRequired(bytes32 _operation, address _initiator, address _to, uint _value, bytes _data);
	event TransactionSent(bytes32 _transaction, address _finalSigner, address _to, uint _value, bytes _data);

	/// Price in wei of each equal share of the partnership
	uint public sharePrice;

	/// Flag indicating whether or not all partners have paid for their share
	bool public funded;

	/// Array of partner addresses
	address [] public partners;

	/// Collection of partner records
	mapping(address => Partner) public partnerRecords;

	/// Count of partners
	uint public partnerCount;

	/// Count of partners who have paid for their share
	uint public paidPartnerCount;

	/// Collection of pending transactions (ie send X ETH to Y with Z data)
	mapping(bytes32 => Transaction) public transactions;

	/// Collection of pending operations (ie internal function calls)
	mapping(bytes32 => Operation) public operations;

	struct Partner {
		bool isPartner;
		/// Flag indicating that the partner has paid for their share
		bool paid;
		/// Total amount loaned to the partnership by the partner
		uint loanBalance;
	}

	struct Transaction {
		address to;
		uint value;
		bytes data;
		/// Total number of partners that have confirmed/voted
		uint voteCount;
		/// Collection of partners that have confirmed/voted
		mapping(address => uint) votes;
	}

	struct Operation {
		uint voteCount;
		mapping(address => uint) votes;
	}

	modifier onlyFunded {
		if (funded)
		_
	}

	modifier onlyPartner {
		if (isPartner(msg.sender))
		_
	}

	/// Allows the call iff all partners have made the same call
	modifier onlyAllPartners(bytes32 _operation) {
		confirmOperation(_operation);
		if (operations[_operation].voteCount == partnerCount)
		_
	}

	function Partnership(address[] _partners, uint _sharePrice) {
		funded = false;
		sharePrice = _sharePrice;
		partners = _partners;
		for (uint i = 0; i < _partners.length; i++) {
			partnerRecords[_partners[i]].isPartner = true;
		}
		partnerCount = _partners.length;
	}

	function() {
		if (msg.value > 0) {
			if (funded) {
				if (partnerRecords[msg.sender].isPartner) {
					partnerRecords[msg.sender].loanBalance += msg.value;
				}
			}
			else {
				if (partnerRecords[msg.sender].isPartner) {
					if (partnerRecords[msg.sender].paid) {
						throw;
					}
					else {
						if (msg.value == sharePrice) {
							partnerRecords[msg.sender].paid = true;
							paidPartnerCount += 1;
							if (paidPartnerCount == partnerCount) {
								funded = true;
							}
						}
						else {
							throw;
						}
					}
				}
				else {
					throw;
				}
			}
			Deposit(msg.sender, msg.value);
		}
	}

	function isPartner(address _address) returns (bool) {
		return partnerRecords[_address].isPartner;
	}

	/// Adds a proposed transaction to be confirmed by other partners
	function proposeTransaction(address _to, uint _value, bytes _data) onlyFunded onlyPartner external returns (bytes32) {
		bytes32 hash = sha3(msg.data, block.number);

		var transaction = transactions[hash];

		transaction.to = _to;
		transaction.value = _value;
		transaction.data = _data;
		transaction.voteCount = 1;
		transaction.votes[msg.sender] = 1;

		ConfirmationRequired(hash, msg.sender, _to, _value, _data);

		return hash;
	}

	/// Confirms an existing proposed transaction and executes it if all partners have confirmed
	function confirmTransaction(bytes32 _id) onlyFunded onlyPartner external {
		var transaction = transactions[_id];

		if (transaction.to == 0)
			throw;

		if (transaction.votes[msg.sender] == 1)
			throw;

		transaction.voteCount += 1;
		transaction.votes[msg.sender] = 1;

		if (transaction.voteCount == partnerCount) {
			TransactionSent(_id, msg.sender, transaction.to, transaction.value, transaction.data);
			transactions[_id].to.call.value(transactions[_id].value)(transactions[_id].data);
			delete transactions[_id];
		}
	}

	function dissolve() onlyFunded onlyAllPartners(sha3(msg.data)) external {
		uint payout = this.balance / partnerCount;
		for ( uint i = 0; i < partnerCount; i++ ) {
			partners[i].send(payout);
		}
		suicide(partners[0]);
	}

	function confirmOperation(bytes32 _operation) internal {
		if (!isPartner(msg.sender))
			throw;

		if (operations[_operation].votes[msg.sender] == 1)
			throw;

		operations[_operation].voteCount += 1;
		operations[_operation].votes[msg.sender] = 1;
	}
}

/// Partnership
/// Requires all pre-defined partners agreement on transactions and operations.
contract Partnership
{
	event Deposit(address _from, uint _value);
	event ConfirmationRequired(bytes32 _operation, address _initiator, address _to, uint _value, bytes _data);
	event TransactionSent(bytes32 _transaction, address _finalSigner, address _to, uint _value, bytes _data);

	/// Array of partner addresses
	address [] partners;

	/// Collection of partner addresses (1 => 'partner', 0/unset => 'not partner')
	mapping(address => uint) public partnerRecords;

	/// Count of partners
	uint public partnerCount;

	/// Collection of pending transactions (ie send X ETH to Y with Z data)
	mapping(bytes32 => Transaction) public transactions;

	/// Collection of pending operations (ie internal function calls)
	mapping(bytes32 => Operation) public operations;

	struct Transaction {
		address to;
		uint value;
		bytes data;
		/// Total number of partners that have confirmed/voted
		uint voteCount;
		/// Collection of partners that have confirmed/voted
		mapping(address => uint) votes;
	}

	struct Operation {
		uint voteCount;
		mapping(address => uint) votes;
	}

	modifier onlyPartner {
		if (isPartner(msg.sender))
		_
	}

	/// Allows the call iff all partners have made the same call
	modifier onlyAllPartners(bytes32 _operation) {
		confirmOperation(_operation);
		if (operations[_operation].voteCount == partnerCount)
		_
	}

	function Partnership(address[] _partners) {
		partners = _partners;
		for (uint i = 0; i < _partners.length; i++) {
			partnerRecords[_partners[i]] = 1;
		}
		partnerCount = _partners.length;
	}

	function() {
		if (msg.value > 0)
			Deposit(msg.sender, msg.value);
	}

	function isPartner(address _address) returns (bool) {
		return partnerRecords[_address] == 1;
	}

	/// Adds a proposed transaction to be confirmed by other partners
	function proposeTransaction(address _to, uint _value, bytes _data) onlyPartner external returns (bytes32) {
		bytes32 hash = sha3(msg.data, block.number);

		var transaction = transactions[hash];

		transaction.to = _to;
		transaction.value = _value;
		transaction.data = _data;
		transaction.voteCount = 1;
		transaction.votes[msg.sender] = 1;

		ConfirmationRequired(hash, msg.sender, _to, _value, _data);

		return hash;
	}

	/// Confirms an existing proposed transaction and executes it if all partners have confirmed
	function confirmTransaction(bytes32 _id) onlyPartner external {
		var transaction = transactions[_id];

		if (transaction.to == 0)
			throw;

		if (transaction.votes[msg.sender] == 1)
			throw;

		transaction.voteCount += 1;
		transaction.votes[msg.sender] = 1;

		if (transaction.voteCount == partnerCount) {
			TransactionSent(_id, msg.sender, transaction.to, transaction.value, transaction.data);
			transactions[_id].to.call.value(transactions[_id].value)(transactions[_id].data);
			delete transactions[_id];
		}
	}

	function kill(address _to) onlyAllPartners(sha3(msg.data)) external {
		suicide(_to);
	}

	function dissolve() onlyAllPartners(sha3(msg.data)) external {
		uint payout = this.balance / partnerCount;
		for ( uint i = 0; i < partnerCount; i++ ) {
			partners[i].send(payout);
		}
		suicide(partners[0]);
	}

	function confirmOperation(bytes32 _operation) internal {
		if (!isPartner(msg.sender))
			throw;

		if (operations[_operation].votes[msg.sender] == 1)
			throw;

		operations[_operation].voteCount += 1;
		operations[_operation].votes[msg.sender] = 1;
	}
}


Don't allow creatures to have negative gas.

import "Board";

contract CreatureBuilderStub {
  function build_creature() returns (Creature result) {}
}

contract BrainStub {
  function notify_of_turn() {}
}

contract Creature {
  address public admin;
  uint public gas;
  uint public hp;
  bool public dead;
  uint public species;
  address public brain;
  CreatureBuilderStub public creature_builder;
  bool public turn_active;
  address public gamemaster;
  Board public board;
  uint public location;

  modifier auth(address authorized_user) { if (msg.sender == authorized_user) _ }
  modifier requires_turn {
    if (turn_active && (msg.sender == brain)) {
      turn_active = false;
      _
    }
  }

  function Creature() {
    admin = msg.sender;
  }

  function validate() returns (uint8 result) {
    return 42;
  }

  function notify_of_turn() auth(gamemaster) {
    turn_active = true;
    BrainStub(brain).notify_of_turn();
  }

  function set_hp(uint _hp) auth(admin) {
    hp = _hp;
  }

  function set_species(uint _species) auth(admin) {
    species = _species;
  }

  function set_brain(address _brain) auth(admin) {
    brain = _brain;
  }

  function set_admin(address _admin) auth(admin) {
    admin = _admin;
  }

  function set_gas(uint _gas) auth(admin) {
    gas = _gas;
  }

  function set_creature_builder(CreatureBuilderStub _creature_builder) auth(admin) {
    creature_builder = _creature_builder;
  }

  function set_gamemaster(address _gamemaster) auth(admin) {
    gamemaster = _gamemaster;
  }

  function set_board(Board _board) auth(admin) {
    board = _board;
  }

  function set_location(uint _location) auth(admin) {
    location = _location;
  }

  function deduct(uint amount) auth(gamemaster) {
    if (amount < gas) {
      gas -= amount;
    } else {
      gas = 0;
      dead = true;
    }
  }

  function move(uint8 direction) requires_turn {
    uint target = board.neighbor(location, direction);
    if (board.creature_at_location(target) == 0) {
      board.leave_square(location);
      board.enter_square(target);
      location = target;
    }
  }

  function harvest() requires_turn {
    gas += board.harvest(location);
  }

  function attack(uint8 direction) requires_turn {
    uint target = board.neighbor(location, direction);
    Creature target_creature = Creature(board.creature_at_location(target));
    target_creature.damage();
  }

  function reproduce(uint8 direction, address new_brain, uint endowment) requires_turn {
    uint target = board.neighbor(location, direction);
    if ((board.creature_at_location(target) == 0) && (endowment <= gas)) {
      Creature new_creature = creature_builder.build_creature();

      new_creature.set_location(target);
      new_creature.set_hp(3);
      new_creature.set_species(species);
      new_creature.set_board(board);

      new_creature.set_admin(admin);

      board.spawn(target, address(new_creature));
    }
  }

  function damage() {
    hp -= 1;
    if (hp == 0) {
      dead = true;
      board.report_death(location, gas);
    }
  }
}

import "Board";

contract CreatureBuilderStub {
  function build_creature() returns (Creature result) {}
}

contract BrainStub {
  function notify_of_turn() {}
}

contract Creature {
  address public admin;
  uint public gas;
  uint public hp;
  bool public dead;
  uint public species;
  address public brain;
  CreatureBuilderStub public creature_builder;
  bool public turn_active;
  address public gamemaster;
  Board public board;
  uint public location;

  modifier auth(address authorized_user) { if (msg.sender == authorized_user) _ }
  modifier requires_turn {
    if (turn_active && (msg.sender == brain)) {
      turn_active = false;
      _
    }
  }

  function Creature() {
    admin = msg.sender;
  }

  function validate() returns (uint8 result) {
    return 42;
  }

  function notify_of_turn() auth(gamemaster) {
    turn_active = true;
    BrainStub(brain).notify_of_turn();
  }

  function set_hp(uint _hp) auth(admin) {
    hp = _hp;
  }

  function set_species(uint _species) auth(admin) {
    species = _species;
  }

  function set_brain(address _brain) auth(admin) {
    brain = _brain;
  }

  function set_admin(address _admin) auth(admin) {
    admin = _admin;
  }

  function set_gas(uint _gas) auth(admin) {
    gas = _gas;
  }

  function set_creature_builder(CreatureBuilderStub _creature_builder) auth(admin) {
    creature_builder = _creature_builder;
  }

  function set_gamemaster(address _gamemaster) auth(admin) {
    gamemaster = _gamemaster;
  }

  function set_board(Board _board) auth(admin) {
    board = _board;
  }

  function set_location(uint _location) auth(admin) {
    location = _location;
  }

  function deduct(uint amount) auth(gamemaster) {
    gas -= amount;
  }

  function move(uint8 direction) requires_turn {
    uint target = board.neighbor(location, direction);
    if (board.creature_at_location(target) == 0) {
      board.leave_square(location);
      board.enter_square(target);
      location = target;
    }
  }

  function harvest() requires_turn {
    gas += board.harvest(location);
  }

  function attack(uint8 direction) requires_turn {
    uint target = board.neighbor(location, direction);
    Creature target_creature = Creature(board.creature_at_location(target));
    target_creature.damage();
  }

  function reproduce(uint8 direction, address new_brain, uint endowment) requires_turn {
    uint target = board.neighbor(location, direction);
    if ((board.creature_at_location(target) == 0) && (endowment <= gas)) {
      Creature new_creature = creature_builder.build_creature();

      new_creature.set_location(target);
      new_creature.set_hp(3);
      new_creature.set_species(species);
      new_creature.set_board(board);

      new_creature.set_admin(admin);

      board.spawn(target, address(new_creature));
    }
  }

  function damage() {
    hp -= 1;
    if (hp == 0) {
      dead = true;
      board.report_death(location, gas);
    }
  }
}


remove unneccessary dist

remove unneccessary dist

pragma solidity ^0.4.11;

/* taking ideas from FirstBlood token */
contract SafeMath {

    function safeAdd(uint256 x, uint256 y) internal returns(uint256) {
        uint256 z = x + y;
        assert((z >= x) && (z >= y));
        return z;
    }

    function safeSubtract(uint256 x, uint256 y) internal returns(uint256) {
        assert(x >= y);
        uint256 z = x - y;
        return z;
    }

    function safeMult(uint256 x, uint256 y) internal returns(uint256) {
        uint256 z = x * y;
        assert((x == 0)||(z/x == y));
        return z;
    }
}

contract Token {
    uint256 public totalSupply;

    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);
}

/*  ERC 20 token */
contract StandardToken is Token, SafeMath {

    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    modifier onlyPayloadSize(uint numwords) {
        assert(msg.data.length == numwords * 32 + 4);
        _;
    }

    function transfer(address _to, uint256 _value)
    returns (bool success)
    {
        if (balances[msg.sender] >= _value && _value > 0 && balances[_to] + _value > balances[_to]) {
            balances[msg.sender] = safeSubtract(balances[msg.sender], _value);
            balances[_to] = safeAdd(balances[_to], _value);
            Transfer(msg.sender, _to, _value);
            return true;
        } else {
            return false;
        }
    }

    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[_to]) {
            balances[_to] = safeAdd(balances[_to], _value);
            balances[_from] = safeSubtract(balances[_from], _value);
            allowed[_from][msg.sender] = safeSubtract(allowed[_from][msg.sender], _value);
            Transfer(_from, _to, _value);
            return true;
        } else {
            return false;
        }
    }

    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }

    function approve(address _spender, uint256 _value)
    onlyPayloadSize(2)
    returns (bool success)
    {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender)
    constant
    onlyPayloadSize(2)
    returns (uint256 remaining)
    {
        return allowed[_owner][_spender];
    }
}

/* Taking ideas from BAT token */
contract PLToken is StandardToken {

    // Token metadata
    string public constant name = "Pre-Leo Token";
    string public constant symbol = "PLT";
    uint256 public constant decimals = 18;
    string public version = "0.9";

    // Fundraising parameters
    enum ContractState { Fundraising, Finalized, Redeeming, Paused }
    ContractState public state;           // Current state of the contract
    ContractState private savedState;     // State of the contract before pause

    uint256 public fundingStartBlock;        // These two blocks need to be chosen to comply with the
    uint256 public fundingEndBlock;          // start date and 28 day duration requirements
    uint256 public exchangeRateChangesBlock; // block number that triggers the exchange rate change

    address public admin1; // First administrator for multi-sig mechanism
    address public admin2; // Second administrator for multi-sig mechanism

    uint256 public constant TOKEN_FIRST_EXCHANGE_RATE = 200; // 200 PLTs per 1 ETH
    uint256 public constant TOKEN_SECOND_EXCHANGE_RATE = 175; // 175 PLTs per 1 ETH
    uint256 public constant TOKEN_CREATION_CAP = 10 * (10**6) * 10**decimals; // 10 million PLTs
    uint256 public constant ETH_RECEIVED_CAP = 50 * (10**3) * 10**decimals; // 50 000 ETH
    uint256 public constant ETH_RECEIVED_MIN = 10 * (10**3) * 10**decimals; // 10 000 ETH
    uint256 public constant TOKEN_MIN = 1 * 10**decimals; // 1 NET

    // We need to keep track of how much ether have been contributed, since we have a cap for ETH too
    uint256 public totalReceivedEth = 0;

    // Since we have different exchange rates at different stages, we need to keep track
    // of how much ether each contributed in case that we need to issue a refund
    mapping (address => uint256) private ethBalances;
    mapping (address => bytes32) private multiSigHashes; // store the hashes of admins' msg.data

    // Events used for logging
    event LogRefund(address indexed _to, uint256 _value);
    event LogCreatePLT(address indexed _to, uint256 _value);
    event LogRedeemPLT(address indexed _from, uint256 _value, string _leoAddress);

    modifier isFinalized() {
        require(state == ContractState.Finalized);
        _;
    }

    modifier isFundraising() {
        require(state == ContractState.Fundraising);
        _;
    }

    modifier isRedeeming() {
        require(state == ContractState.Redeeming);
        _;
    }

    modifier isPaused() {
        require(state == ContractState.Paused);
        _;
    }

    modifier notPaused() {
        require(state != ContractState.Paused);
        _;
    }

    modifier isFundraisingIgnorePaused() {
        require(state == ContractState.Fundraising || (state == ContractState.Paused && savedState == ContractState.Fundraising));
        _;
    }

    modifier onlyOwner() {
        // check if transaction sender is admin.
        require (msg.sender == admin1 || msg.sender == admin2);
        // if yes, store his msg.data.
        multiSigHashes[msg.sender] = sha3(msg.data);
        // check if his stored msg.data hash equals to the one of the other admin
        if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) {
            // if yes, both admins agreed - continue.
            _;
        } else {
            // if not (yet), return.
            return;
        }
    }

    modifier minimumReached() {
        require(totalReceivedEth >= ETH_RECEIVED_MIN);
        _;
    }

    // Constructor
    function PLToken(
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock,
        uint256 _exchangeRateChangesBlock,
        address _admin1,
        address _admin2)
    {
        // Check that the parameters make sense
        require(block.number <= _fundingStartBlock); // The start of the fundraising should happen in the future
        require(_fundingStartBlock <= _exchangeRateChangesBlock); // The exchange rate change should happen after the start of the fundraising
        require(_exchangeRateChangesBlock <= _fundingEndBlock); // And the end of the fundraising should happen after the exchange rate change
        require (_admin1 != 0x0); // admin1 address must be set
        require (_admin2 != 0x0); // admin2 address must be set

        // Contract state
        state = ContractState.Fundraising;
        savedState = ContractState.Fundraising;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        exchangeRateChangesBlock = _exchangeRateChangesBlock;
        totalSupply = 0;

        admin1 = _admin1;
        admin2 = _admin2;
    }

    //Debugging: Method for checking if admins agree on a transaction right now or not.
    function checkMultisigStatus()
    constant
    returns (bool success)
    {
    if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) {
        return true;
        } else {
        return false;
        }
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transfer(address _to, uint256 _value)
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(2)
    returns (bool success)
    {
        return super.transfer(_to, _value);
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transferFrom(address _from, address _to, uint256 _value)
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(3)
    returns (bool success)
    {
        return super.transferFrom(_from, _to, _value);
    }

    /// @dev Accepts ether and creates new NET tokens
    function createTokens()
    payable
    external
    isFundraising
    {
        require(block.number >= fundingStartBlock);
        require(block.number <= fundingEndBlock);
        require(msg.value > 0);

        // First we check the ETH cap, as it's easier to calculate, return
        // the contribution if the cap has been reached already
        uint256 checkedReceivedEth = safeAdd(totalReceivedEth, msg.value);
        require(checkedReceivedEth <= ETH_RECEIVED_CAP);

        // If all is fine with the ETH cap, we continue to check the
        // minimum amount of tokens and the cap for how many tokens
        // have been generated so far
        uint256 tokens = safeMult(msg.value, getCurrentTokenPrice());
        require(tokens >= TOKEN_MIN);
        uint256 checkedSupply = safeAdd(totalSupply, tokens);
        require(checkedSupply <= TOKEN_CREATION_CAP);

        // Only when all the checks have passed, then we update the state (ethBalances,
        // totalReceivedEth, totalSupply, and balances) of the contract
        ethBalances[msg.sender] = safeAdd(ethBalances[msg.sender], msg.value);
        totalReceivedEth = checkedReceivedEth;
        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;  // safeAdd not needed; bad semantics to use here

        // Log the creation of this tokens
        LogCreatePLT(msg.sender, tokens);
    }

    /// @dev Returns the current token price
    function getCurrentTokenPrice()
    private
    constant
    returns (uint256 currentPrice)
    {
        if (block.number < exchangeRateChangesBlock) {
            return TOKEN_FIRST_EXCHANGE_RATE;
        } else {
            return TOKEN_SECOND_EXCHANGE_RATE;
        }
    }

    /// @dev Redeems PLTs and records the LEO address of the sender
    function redeemTokens(bytes32 leoAddress)
    external
    isRedeeming
    {
        uint256 netVal = balances[msg.sender];
        require(netVal >= TOKEN_MIN); // At least TOKEN_MIN tokens have to be redeemed

        // Burn Tokens on redemption
        //if (!super.transfer(0x0, netVal)) throw;
        require(super.transfer(0x0, netVal));
        // Log the redeeming of this tokens
        LogRedeemPLT(msg.sender, netVal, leoAddress);
    }

    /// @dev Allows to transfer ether from the contract as soon as the minimum is reached
    function retrieveEth(uint256 _value, address _safe)
    external
    minimumReached
    onlyOwner
    {
        require(_value <= this.balance);
        // make sure a recipient was defined !
        require (_safe != 0x0);
        // send the eth to where admins agree upon
        _safe.transfer(_value);
    }

    /// @dev Ends the fundraising period and sends the ETH to wherever the admins agree upon
    function finalize(address _safe)
    external
    isFundraising
    minimumReached
    onlyOwner  // Only the admins calling this method exactly the same way can finalize the sale.
    {
        require(block.number > fundingEndBlock || totalSupply >= TOKEN_CREATION_CAP || totalReceivedEth >= ETH_RECEIVED_CAP); // Only allow to finalize the contract before the ending block if we already reached any of the two caps
        // make sure a recipient was defined !
        require (_safe != 0x0);
        // Move the contract to Finalized state
        state = ContractState.Finalized;
        savedState = ContractState.Finalized;

        // Send the ETH to where admins agree upon.
        _safe.transfer(this.balance);
    }

    /// @dev Starts the redeeming period
    function startRedeeming()
    external
    isFinalized // The redeeming period can only be started after the contract is finalized
    onlyOwner   // Only both admins calling this method can initiate the redeeming period
    {
        // Move the contract to Redeeming state
        state = ContractState.Redeeming;
        savedState = ContractState.Redeeming;
    }

    /// @dev Pauses the contract
    function pause()
    external
    notPaused   // Prevent the contract getting stuck in the Paused state
    onlyOwner   // Only both admins calling this method can pause the contract
    {
        // Move the contract to Paused state
        savedState = state;
        state = ContractState.Paused;
    }

    /// @dev Proceeds with the contract
    function proceed()
    external
    isPaused
    onlyOwner   // Only both admins calling this method can proceed with the contract
    {
        // Move the contract to the previous state
        state = savedState;
    }

    /// @dev Allows contributors to recover their ether in case the minimum funding goal is not reached
    function refund()
    external
    isFundraisingIgnorePaused // Refunding is only possible in the fundraising phase (no matter if paused) by definition
    {
        require(block.number > fundingEndBlock); // Prevents refund until fundraising period is over
        require(totalReceivedEth < ETH_RECEIVED_MIN);  // No refunds if the minimum has been reached

        uint256 netVal = balances[msg.sender];
        require(netVal > 0);
        uint256 ethVal = ethBalances[msg.sender];
        require(ethVal > 0);

        // Update the state only after all the checks have passed
        balances[msg.sender] = 0;
        ethBalances[msg.sender] = 0;
        totalSupply = safeSubtract(totalSupply, netVal); // Extra safe

        // Log this refund
        LogRefund(msg.sender, ethVal);

        // Send the contributions only after we have updated all the balances
        // If you're using a contract, make sure it works with .transfer() gas limits
        msg.sender.transfer(ethVal);
    }
}