Add setBlockInterval interface

Add setBlockInterval interface

pragma solidity 0.4.24;

import "../common/EconomicalType.sol";
import "../common/Admin.sol";
import "../common/ReservedAddrPublic.sol";
import "../../interaction/interface/ISysConfig.sol";

/// @title System config contract
/// @author ["Cryptape Technologies <contact@cryptape.com>"]
contract SysConfig is ISysConfig, EconomicalType, ReservedAddrPublic {

    /// @notice only chain_name, operator, website can be updated
    uint delayBlockNumber;
    bool checkPermission;
    bool checkSendTxPermission;
    bool checkCreateContractPermission;
    bool checkQuota;
    bool checkFeeBackPlatform;
    address chainOwner;
    string chainName;
    uint32 chainId;
    string operator;
    string website;
    uint64 blockInterval;
    EconomicalModel economicalModel;
    TokenInfo tokenInfo;

    Admin admin = Admin(adminAddr);
    uint chainIdV1;
    bool autoExec;

    modifier onlyAdmin {
        if (admin.isAdmin(msg.sender))
            _;
        else return;
    }

    struct TokenInfo {
        string name;
        string symbol;
        string avatar;
    }

    /// @notice Setup
    /// @param flags :
    ///    0: _checkPermission
    ///    1: _checkSendTxPermission
    ///    2: _checkCreateContractPermission
    ///    3: _checkQuota
    ///    4: _checkFeeBackPlatform
    ///    5: _autoExec
    constructor(
        uint _delayBlockNumber,
        address _chainOwner,
        string _chainName,
        uint _chainId,
        string _operator,
        string _website,
        uint64 _blockInterval,
        EconomicalModel _economicalModel,
        string _name,
        string _symbol,
        string _avatar,
        bool[] flags
    )
        public
    {
        require(_chainId > 0, "The chainId should larger than zero.");
        delayBlockNumber = _delayBlockNumber;
        checkPermission = flags[0];
        checkSendTxPermission = flags[1];
        checkCreateContractPermission = flags[2];
        checkQuota = flags[3];
        checkFeeBackPlatform = flags[4];
        autoExec = flags[5];
        chainOwner = _chainOwner;
        chainName = _chainName;
        chainId = uint32(_chainId);
        chainIdV1 = _chainId;
        operator = _operator;
        website = _website;
        blockInterval = _blockInterval;
        economicalModel = _economicalModel;
        tokenInfo = TokenInfo({
            name: _name,
            symbol: _symbol,
            avatar: _avatar
        });
    }

    function setOperator(string _operator)
        external
        onlyAdmin
    {
        operator = _operator;
    }

    function setWebsite(string _website)
        external
        onlyAdmin
    {
        website = _website;
    }

    function setChainName(string _chainName)
        external
        onlyAdmin
    {
        chainName = _chainName;
    }

    function setBlockInterval(uint64 _blockInterval)
        external
        onlyAdmin
    {
        blockInterval = _blockInterval;
    }

    function updateToChainIdV1()
        external
        onlyAdmin
    {
        chainIdV1 = uint(chainId);
    }

    function getDelayBlockNumber()
        public
        view
        returns (uint)
    {
        return delayBlockNumber;
    }

    function getPermissionCheck()
        public
        view
        returns (bool)
    {
        return checkPermission;
    }

    function getSendTxPermissionCheck()
        public
        view
        returns (bool)
    {
        return checkSendTxPermission;
    }

    function getCreateContractPermissionCheck()
        public
        view
        returns (bool)
    {
        return checkCreateContractPermission;
    }

    function getQuotaCheck()
        public
        view
        returns (bool)
    {
        return checkQuota && (economicalModel == EconomicalModel.Quota);
    }

    function getFeeBackPlatformCheck()
        public
        view
        returns (bool)
    {
        return checkFeeBackPlatform;
    }

    function getChainOwner()
        public
        view
        returns (address)
    {
        return chainOwner;
    }

    function getChainName()
        public
        view
        returns (string)
    {
        return chainName;
    }

    function getChainId()
        public
        view
        returns (uint32)
    {
        return chainId;
    }

    function getChainIdV1()
        public
        view
        returns (uint)
    {
        return chainIdV1;
    }

    function getOperator()
        public
        view
        returns (string)
    {
        return operator;
    }

    function getWebsite()
        public
        view
        returns (string)
    {
        return website;
    }

    function getBlockInterval()
        public
        view
        returns (uint64)
    {
        return blockInterval;
    }

    function getEconomicalModel()
        public
        view
        returns (EconomicalModel)
    {
        return economicalModel;
    }

    function getTokenInfo()
        public
        view
        returns(string name, string symbol, string avatar)
    {
        name = tokenInfo.name;
        symbol = tokenInfo.symbol;
        avatar = tokenInfo.avatar;
    }

    function getAutoExec()
        public
        view
        returns (bool)
    {
        return autoExec;
    }
}

pragma solidity 0.4.24;

import "../common/EconomicalType.sol";
import "../common/Admin.sol";
import "../common/ReservedAddrPublic.sol";
import "../../interaction/interface/ISysConfig.sol";

/// @title System config contract
/// @author ["Cryptape Technologies <contact@cryptape.com>"]
contract SysConfig is ISysConfig, EconomicalType, ReservedAddrPublic {

    /// @notice only chain_name, operator, website can be updated
    uint delayBlockNumber;
    bool checkPermission;
    bool checkSendTxPermission;
    bool checkCreateContractPermission;
    bool checkQuota;
    bool checkFeeBackPlatform;
    address chainOwner;
    string chainName;
    uint32 chainId;
    string operator;
    string website;
    uint64 blockInterval;
    EconomicalModel economicalModel;
    TokenInfo tokenInfo;

    Admin admin = Admin(adminAddr);
    uint chainIdV1;
    bool autoExec;

    modifier onlyAdmin {
        if (admin.isAdmin(msg.sender))
            _;
        else return;
    }

    struct TokenInfo {
        string name;
        string symbol;
        string avatar;
    }

    /// @notice Setup
    /// @param flags :
    ///    0: _checkPermission
    ///    1: _checkSendTxPermission
    ///    2: _checkCreateContractPermission
    ///    3: _checkQuota
    ///    4: _checkFeeBackPlatform
    ///    5: _autoExec
    constructor(
        uint _delayBlockNumber,
        address _chainOwner,
        string _chainName,
        uint _chainId,
        string _operator,
        string _website,
        uint64 _blockInterval,
        EconomicalModel _economicalModel,
        string _name,
        string _symbol,
        string _avatar,
        bool[] flags
    )
        public
    {
        require(_chainId > 0, "The chainId should larger than zero.");
        delayBlockNumber = _delayBlockNumber;
        checkPermission = flags[0];
        checkSendTxPermission = flags[1];
        checkCreateContractPermission = flags[2];
        checkQuota = flags[3];
        checkFeeBackPlatform = flags[4];
        autoExec = flags[5];
        chainOwner = _chainOwner;
        chainName = _chainName;
        chainId = uint32(_chainId);
        chainIdV1 = _chainId;
        operator = _operator;
        website = _website;
        blockInterval = _blockInterval;
        economicalModel = _economicalModel;
        tokenInfo = TokenInfo({
            name: _name,
            symbol: _symbol,
            avatar: _avatar
        });
    }

    function setOperator(string _operator)
        external
        onlyAdmin
    {
        operator = _operator;
    }

    function setWebsite(string _website)
        external
        onlyAdmin
    {
        website = _website;
    }

    function setChainName(string _chainName)
        external
        onlyAdmin
    {
        chainName = _chainName;
    }

    function updateToChainIdV1()
        external
        onlyAdmin
    {
        chainIdV1 = uint(chainId);
    }

    function getDelayBlockNumber()
        public
        view
        returns (uint)
    {
        return delayBlockNumber;
    }

    function getPermissionCheck()
        public
        view
        returns (bool)
    {
        return checkPermission;
    }

    function getSendTxPermissionCheck()
        public
        view
        returns (bool)
    {
        return checkSendTxPermission;
    }

    function getCreateContractPermissionCheck()
        public
        view
        returns (bool)
    {
        return checkCreateContractPermission;
    }

    function getQuotaCheck()
        public
        view
        returns (bool)
    {
        return checkQuota && (economicalModel == EconomicalModel.Quota);
    }

    function getFeeBackPlatformCheck()
        public
        view
        returns (bool)
    {
        return checkFeeBackPlatform;
    }

    function getChainOwner()
        public
        view
        returns (address)
    {
        return chainOwner;
    }

    function getChainName()
        public
        view
        returns (string)
    {
        return chainName;
    }

    function getChainId()
        public
        view
        returns (uint32)
    {
        return chainId;
    }

    function getChainIdV1()
        public
        view
        returns (uint)
    {
        return chainIdV1;
    }

    function getOperator()
        public
        view
        returns (string)
    {
        return operator;
    }

    function getWebsite()
        public
        view
        returns (string)
    {
        return website;
    }

    function getBlockInterval()
        public
        view
        returns (uint64)
    {
        return blockInterval;
    }

    function getEconomicalModel()
        public
        view
        returns (EconomicalModel)
    {
        return economicalModel;
    }

    function getTokenInfo()
        public
        view
        returns(string name, string symbol, string avatar)
    {
        name = tokenInfo.name;
        symbol = tokenInfo.symbol;
        avatar = tokenInfo.avatar;
    }

    function getAutoExec()
        public
        view
        returns (bool)
    {
        return autoExec;
    }
}


boooorring

boooorring

pragma solidity ^0.4.11;
contract Bet is usingOraclize {
  enum BET_STATES {
    OPEN,
    TEAM_ONE_WON,
    TEAM_TWO_WON,
    DRAW,
    ORACLE_UNDECIDED
    }

  BET_STATES bet_state = BET_STATES.OPEN;
  bool public is_featured;
  string public title;
  string public description;
  string public category;
  string public team_0; // Team 0 identifier
  string public team_1; // Team 1 identifier
  uint public team_0_bet_sum;
  uint public team_1_bet_sum;

  uint public block_match_begin;
  uint public block_match_end;
  uint public block_hard_deadline; // Hard deadline to end bet
  uint public block_suicide_deadline; // Suicide deadline > hard_deadline (this must be big, so people can withdraw their funds)

  uint8 oracle_retries; // How many times the oracle tried to set the score on the bet
  uint constant oracle_retry_interval = 100; // Interval for retries (in blocks)

  string url_oraclize;

  event new_betting(uint8 for_team_idx, address from, uint amount);
  event new_winner_declared(BET_STATES winner);

  function arbitrate(bool winner) {
    assert(block.number >= block_hard_deadline);
    assert(bet_state == ORACLE_UNDECIDED);

    if (winner == 0)
       bet_state = BET_STATES.TEAM_ONE_WON;
    else
       bet_state = BET_STATES.TEAM_TWO_WON;
  }

  function __callback(bytes32 myid, string result) {
    // Cannot call after hard deadline
    assert(block.number < block_hard_deadline);
    // Oraclize should call this
    assert(msg.sender == oraclize_cbAddress());
    // Must be called after the bet ends
    assert(block.number >= block_match_end);
    // Can call only when bet is open or undecided
    assert(bet_state == BET_STATES.OPEN || bet_state == BET_STATES.ORACLE_UNDECIDED);

    oracle_retries += 1;
    // Oracle is retrying
    if (bet_state == BET_STATES.ORACLE_UNDECIDED) {
      assert(block.number >= (block_match_end + (oracle_retry_interval * oracle_retries)));
    }
    if (result == team_0)
      bet_state = BET_STATES.TEAM_ONE_WON;
    else if (result == team_1)
      bet_state = BET_STATES.TEAM_TWO_WON;
    else
      bet_state = BET_STATES.ORACLE_UNDECIDED;

    new_winner_declared(bet_state);
  }

  function update_result() payable {
    oraclize_query('URL', url_oraclize);
  }

  function toggle_featured() {
    if (msg.sender != ebets_address()) throw;
    is_featured = !is_featured;
  }

  //
  function bet(bool for_team) {
    assert(block.number < block_match_begin);
    if (for_team == 0)
      team_0_bet_sum += msg.value;
    else
      team_0_bet_sum += msg.value;

    new_betting(for_team_idx, msg.sender, msg.value);
  }

  // Called by the user to collect his reward
  function collect_profit() {

  }

  // If the oracle fails or is not able to get the right answer
  function resolve_conflict(uint8 for_team_idx) {
  }
}

pragma solidity ^0.4.11;
contract Bet is usingOraclize {
  enum BET_STATES {
    OPEN,
    TEAM_ONE_WON,
    TEAM_TWO_WON,
    DRAW,
    ORACLE_UNDECIDED
    }

  BET_STATES bet_state;
  bool public is_featured;
  string public title;
  string public description;
  string public category;
  string public team_0; // Team 0 identifier
  string public team_1; // Team 1 identifier
  uint public team_0_bet_sum;
  uint public team_1_bet_sum;

  uint public block_match_begin;
  uint public block_match_end;
  uint public block_hard_deadline; // Hard deadline to end bet

  uint8 oracle_retries; // How many times the oracle tried to set the score on the bet
  uint constant oracle_retry_interval = 100; // Interval for retries (in blocks)

  string url_oraclize;

  uint8 winner_idx;

  event new_betting(uint8 for_team_idx, address from, amount);
  event new_winner_declared(BET_STATES winner);

  function __callback(bytes32 myid, string result) {
    // Cannot call after hard deadline
    assert(block.number < block_hard_deadline);
    // Oraclize should call this
    assert(msg.sender == oraclize_cbAddress());
    // Must be called after the bet ends
    assert(block.number >= block_match_end);
    // Can call only when bet is open or undecided
    assert(bet_state == BET_STATES.OPEN || bet_state == BET_STATES.ORACLE_UNDECIDED);

    oracle_retries += 1;
    // Oracle is retrying
    if (bet_state == BET_STATES.ORACLE_UNDECIDED) {
      assert(block.number >= (block_match_end + (oracle_retry_interval * oracle_retries)));
    }
    if (result == team_0)
      bet_state = BET_STATES.TEAM_ONE_WON;
    else if (result == team_1)
      bet_state = BET_STATES.TEAM_TWO_WON;
    else
      bet_state = BET_STATES.ORACLE_UNDECIDED;
    new_winner_declared(bet_state);
  }

  function update_result() payable {
    oraclize_query('URL', url_oraclize);
  }

  function toggle_featured() {
    if (msg.sender != ebets_address()) throw;
    is_featured = !is_featured;
  }

  //
  function bet(uint8 for_team_idx) {
    new_betting(for_team_idx, msg.sender, msg.value);
  }

  // Called by the user to collect his reward
  function collect_profit() {

  }

  // If the oracle fails or is not able to get the right answer
  function resolve_conflict(uint8 for_team_idx) {
  }
}


Fix assert/require usage

Fix assert/require usage

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.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;

            if (self.opened == 0) {
                self.opened = block.number;
            }

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

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) {
        if (self.settled > 0 || self.closed == 0)
            throw;
        _;
    }

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

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

    modifier channelSettled(Data storage self) {
        if (self.settled == 0)
            throw;
        _;
    }

    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.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;

            if (self.opened == 0) {
                self.opened = block.number;
            }

            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
        if (message.length != 268) {
            throw;
        }

        // 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
        if (message.length != 196) {
            throw;
        }

        // 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 notClosed modifier to private methods

// Implements standard token interface
// From: https://github.com/slockit/DAO/blob/f640568e694a057aaeb64a0f1049fae27efe818b/Token.sol
// See also https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs

contract TokenInterface {
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    /// Total amount of tokens
    uint256 public totalSupply;

    /// @param _owner The address from which the balance will be retrieved
    /// @return The balance
    function balanceOf(address _owner) constant returns (uint256 balance);

    /// @notice Send `_amount` tokens to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _amount) returns (bool success);

    /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
    /// is approved by `_from`
    /// @param _from The address of the origin of the transfer
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return Whether the transfer was successful or not
    function transferFrom(address _from, address _to, uint256 _amount) returns (bool success);

    /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
    /// its behalf
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _amount The amount of tokens to be approved for transfer
    /// @return Whether the approval was successful or not
    function approve(address _spender, uint256 _amount) returns (bool success);

    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens of _owner that _spender is allowed
    /// to spend
    function allowance(
        address _owner,
        address _spender
    ) constant returns (uint256 remaining);

    event Transfer(address indexed _from, address indexed _to, uint256 _amount);
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _amount
    );
}

contract DynamicToken is TokenInterface {
  address public contractOwner;
  address[] public accounts;
  mapping (address => bool) public accountExists;
  string[] public proofIds;
  mapping (string => bool) proofIdExists;
  uint256 public maxSupply;
  bool public closed;
  address public upgradedContract;

  event TransferFrom(address indexed _from, address indexed _to,  address indexed _spender, uint256 _amount);
  event Issue(address _from, address _to, uint256 _amount, string _proofId);
  event Burn(address _burnFrom, uint256 _amount, address _burner);
  event Close(address _closedBy);
  event Upgrade(address _upgradedContract);

  function DynamicToken() {
    contractOwner = msg.sender;     // contract owner is contract creator
    closed = false;
    maxSupply = 10**7;
    totalSupply = 0;
  }

  // restrict usage to only the owner
  modifier onlyContractOwner {
    if (msg.sender != contractOwner) throw;
    _
  }

  // check if the contract has been closed
  modifier notClosed {
    if (closed) throw;
    _
  }

  // no ether should be transfered to this contract
  modifier noEther() {if (msg.value > 0) throw; _}

  // accessors

  function getAccounts() noEther constant returns (address[] _accounts) {
    return accounts;
  }

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

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

  // mutators

  // tokens are only issued in exchange for a unique proof of contribution
  function issue(address _to, uint256 _amount, string _proofId) notClosed onlyContractOwner noEther returns (bool success) {
    if (balances[_to] + _amount < balances[_to]) throw; // Check for overflow
    if (totalSupply + _amount < totalSupply) throw;     // Check for overflow  (this should never happen)

    if (proofIdExists[_proofId]) return false;
    if (totalSupply + _amount > maxSupply) return false;

    balances[_to] += _amount;
    totalSupply += _amount;
    _indexAccount(_to);
    _indexProofId(_proofId);
    Issue(msg.sender, _to, _amount, _proofId);
    return true;
  }

  function setMaxSupply(uint256 _maxSupply) notClosed onlyContractOwner noEther returns (bool success) {
    if (_maxSupply < totalSupply) throw;

    maxSupply = _maxSupply;
    return true;
  }

  function transferContractOwnership(address _newOwner) notClosed onlyContractOwner noEther returns (bool success) {
    contractOwner = _newOwner;
    return true;
  }

  function transfer(address _to, uint256 _amount) notClosed noEther returns (bool success) {
    return _transfer(msg.sender, _to, _amount);
  }

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

  function transferFrom(address _from, address _to, uint256 _amount) notClosed noEther returns (bool success) {
    if (_amount > allowed[_from][msg.sender]) return false;
    if (!_transfer(_from, _to, _amount)) return false;

    allowed[_from][msg.sender] -= _amount;
    TransferFrom(_from, _to, msg.sender, _amount);
    return true;
  }

  function burn(address _burnFrom, uint256 _amount) notClosed noEther returns (bool success) {
    if( !(msg.sender == _burnFrom || msg.sender == contractOwner) ) throw;
    if (_amount > totalSupply) return false;  // check for underflow
    if (_amount > balances[_burnFrom]) return false;

    balances[_burnFrom] -= _amount;
    totalSupply -= _amount;
    Burn(_burnFrom, _amount, msg.sender);
    return true;
  }

  function upgrade(address _upgradedContract) notClosed onlyContractOwner noEther returns (bool success) {
    upgradedContract = _upgradedContract;
    close();
    Upgrade(_upgradedContract);
    return true;
  }

  function close() notClosed onlyContractOwner noEther returns (bool success) {
    closed = true;
    Close(msg.sender);
    return true;
  }

  function destroyContract() onlyContractOwner noEther {
    selfdestruct(contractOwner);
  }

  // private mutators

  function _transfer(address _from, address _to, uint256 _amount) notClosed private returns (bool success) {
    if (balances[_to] + _amount < balances[_to]) throw;  // Check for overflow
    if (_amount > balances[_from]) return false;

    balances[_to] += _amount;
    balances[_from] -= _amount;
    _indexAccount(_to);
    Transfer(_from, _to, _amount);
    return true;
  }

  function _indexAccount(address _account) notClosed private {
    if (accountExists[_account]) return;
    accountExists[_account] = true;
    accounts.push(_account);
  }

  function _indexProofId(string _proofId) notClosed private {
    if (proofIdExists[_proofId]) return;
    proofIdExists[_proofId] = true;
    proofIds.push(_proofId);
  }

  // throw on malformed calls
  function () {
    throw;
  }
}

// Implements standard token interface
// From: https://github.com/slockit/DAO/blob/f640568e694a057aaeb64a0f1049fae27efe818b/Token.sol
// See also https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs

contract TokenInterface {
    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    /// Total amount of tokens
    uint256 public totalSupply;

    /// @param _owner The address from which the balance will be retrieved
    /// @return The balance
    function balanceOf(address _owner) constant returns (uint256 balance);

    /// @notice Send `_amount` tokens to `_to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return Whether the transfer was successful or not
    function transfer(address _to, uint256 _amount) returns (bool success);

    /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
    /// is approved by `_from`
    /// @param _from The address of the origin of the transfer
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @return Whether the transfer was successful or not
    function transferFrom(address _from, address _to, uint256 _amount) returns (bool success);

    /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
    /// its behalf
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _amount The amount of tokens to be approved for transfer
    /// @return Whether the approval was successful or not
    function approve(address _spender, uint256 _amount) returns (bool success);

    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens of _owner that _spender is allowed
    /// to spend
    function allowance(
        address _owner,
        address _spender
    ) constant returns (uint256 remaining);

    event Transfer(address indexed _from, address indexed _to, uint256 _amount);
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _amount
    );
}

contract DynamicToken is TokenInterface {
  address public contractOwner;
  address[] public accounts;
  mapping (address => bool) public accountExists;
  string[] public proofIds;
  mapping (string => bool) proofIdExists;
  uint256 public maxSupply;
  bool public closed;
  address public upgradedContract;

  event TransferFrom(address indexed _from, address indexed _to,  address indexed _spender, uint256 _amount);
  event Issue(address _from, address _to, uint256 _amount, string _proofId);
  event Burn(address _burnFrom, uint256 _amount, address _burner);
  event Close(address _closedBy);
  event Upgrade(address _upgradedContract);

  function DynamicToken() {
    contractOwner = msg.sender;     // contract owner is contract creator
    closed = false;
    maxSupply = 10**7;
    totalSupply = 0;
  }

  // restrict usage to only the owner
  modifier onlyContractOwner {
    if (msg.sender != contractOwner) throw;
    _
  }

  // check if the contract has been closed
  modifier notClosed {
    if (closed) throw;
    _
  }

  // no ether should be transfered to this contract
  modifier noEther() {if (msg.value > 0) throw; _}

  // accessors

  function getAccounts() noEther constant returns (address[] _accounts) {
    return accounts;
  }

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

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

  // mutators

  // tokens are only issued in exchange for a unique proof of contribution
  function issue(address _to, uint256 _amount, string _proofId) notClosed onlyContractOwner noEther returns (bool success) {
    if (balances[_to] + _amount < balances[_to]) throw; // Check for overflow
    if (totalSupply + _amount < totalSupply) throw;     // Check for overflow  (this should never happen)

    if (proofIdExists[_proofId]) return false;
    if (totalSupply + _amount > maxSupply) return false;

    balances[_to] += _amount;
    totalSupply += _amount;
    _indexAccount(_to);
    _indexProofId(_proofId);
    Issue(msg.sender, _to, _amount, _proofId);
    return true;
  }

  function setMaxSupply(uint256 _maxSupply) notClosed onlyContractOwner noEther returns (bool success) {
    if (_maxSupply < totalSupply) throw;

    maxSupply = _maxSupply;
    return true;
  }

  function transferContractOwnership(address _newOwner) notClosed onlyContractOwner noEther returns (bool success) {
    contractOwner = _newOwner;
    return true;
  }

  function transfer(address _to, uint256 _amount) notClosed noEther returns (bool success) {
    return _transfer(msg.sender, _to, _amount);
  }

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

  function transferFrom(address _from, address _to, uint256 _amount) notClosed noEther returns (bool success) {
    if (_amount > allowed[_from][msg.sender]) return false;
    if (!_transfer(_from, _to, _amount)) return false;

    allowed[_from][msg.sender] -= _amount;
    TransferFrom(_from, _to, msg.sender, _amount);
    return true;
  }

  function burn(address _burnFrom, uint256 _amount) notClosed noEther returns (bool success) {
    if( !(msg.sender == _burnFrom || msg.sender == contractOwner) ) throw;
    if (_amount > totalSupply) return false;  // check for underflow
    if (_amount > balances[_burnFrom]) return false;

    balances[_burnFrom] -= _amount;
    totalSupply -= _amount;
    Burn(_burnFrom, _amount, msg.sender);
    return true;
  }

  function upgrade(address _upgradedContract) notClosed onlyContractOwner noEther returns (bool success) {
    upgradedContract = _upgradedContract;
    close();
    Upgrade(_upgradedContract);
    return true;
  }

  function close() notClosed onlyContractOwner noEther returns (bool success) {
    closed = true;
    Close(msg.sender);
    return true;
  }

  function destroyContract() onlyContractOwner noEther {
    selfdestruct(contractOwner);
  }

  // private mutators

  function _transfer(address _from, address _to, uint256 _amount) private returns (bool success) {
    if (balances[_to] + _amount < balances[_to]) throw;  // Check for overflow
    if (_amount > balances[_from]) return false;

    balances[_to] += _amount;
    balances[_from] -= _amount;
    _indexAccount(_to);
    Transfer(_from, _to, _amount);
    return true;
  }

  function _indexAccount(address _account) private {
    if (accountExists[_account]) return;
    accountExists[_account] = true;
    accounts.push(_account);
  }

  function _indexProofId(string _proofId) private {
    if (proofIdExists[_proofId]) return;
    proofIdExists[_proofId] = true;
    proofIds.push(_proofId);
  }

  // throw on malformed calls
  function () {
    throw;
  }
}


Remediate issue 3.1 in ENS audit

Remediate issue 3.1 in ENS audit

pragma solidity >0.4.18;

/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library Buffer {
    /**
    * @dev Represents a mutable buffer. Buffers have a current value (buf) and
    *      a capacity. The capacity may be longer than the current value, in
    *      which case it can be extended without the need to allocate more memory.
    */
    struct buffer {
        bytes buf;
        uint capacity;
    }

    /**
    * @dev Initializes a buffer with an initial capacity.
    * @param buf The buffer to initialize.
    * @param capacity The number of bytes of space to allocate the buffer.
    * @return The buffer, for chaining.
    */
    function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
        if (capacity % 32 != 0) {
            capacity += 32 - (capacity % 32);
        }
        // Allocate space for the buffer data
        buf.capacity = capacity;
        assembly {
            let ptr := mload(0x40)
            mstore(buf, ptr)
            mstore(ptr, 0)
            mstore(0x40, add(32, add(ptr, capacity)))
        }
        return buf;
    }

    /**
    * @dev Initializes a new buffer from an existing bytes object.
    *      Changes to the buffer may mutate the original value.
    * @param b The bytes object to initialize the buffer with.
    * @return A new buffer.
    */
    function fromBytes(bytes memory b) internal pure returns(buffer memory) {
        buffer memory buf;
        buf.buf = b;
        buf.capacity = b.length;
        return buf;
    }

    function resize(buffer memory buf, uint capacity) private pure {
        bytes memory oldbuf = buf.buf;
        init(buf, capacity);
        append(buf, oldbuf);
    }

    function max(uint a, uint b) private pure returns(uint) {
        if (a > b) {
            return a;
        }
        return b;
    }

    /**
    * @dev Sets buffer length to 0.
    * @param buf The buffer to truncate.
    * @return The original buffer, for chaining..
    */
    function truncate(buffer memory buf) internal pure returns (buffer memory) {
        assembly {
            let bufptr := mload(buf)
            mstore(bufptr, 0)
        }
        return buf;
    }

    /**
    * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The start offset to write to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) {
        require(len <= data.length);

        if (off + len + buf.buf.length > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint dest;
        uint src;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Start address = buffer address + offset + sizeof(buffer length)
            dest := add(add(bufptr, 32), off)
            // Update buffer length if we're extending it
            if gt(add(len, off), buflen) {
                mstore(bufptr, add(len, off))
            }
            src := add(data, 32)
        }

        // Copy word-length chunks while possible
        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = 256 ** (32 - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }

        return buf;
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, len);
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, data.length);
    }

    /**
    * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write the byte at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) {
        if (off > buf.capacity) {
            resize(buf, buf.capacity * 2);
        }

        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Address = buffer address + sizeof(buffer length) + off
            let dest := add(add(bufptr, off), 32)
            mstore8(dest, data)
            // Update buffer length if we extended it
            if eq(off, buflen) {
                mstore(bufptr, add(buflen, 1))
            }
        }
        return buf;
    }

    /**
    * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
        return writeUint8(buf, buf.buf.length, data);
    }

    /**
    * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
    *      exceed the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (left-aligned).
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, max(buf.capacity, len) * 2);
        }

        uint mask = 256 ** len - 1;
        // Right-align data
        data = data >> (8 * (32 - len));
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + sizeof(buffer length) + off + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }

    /**
    * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, off, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chhaining.
    */
    function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, 32);
    }

    /**
    * @dev Writes an integer to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (right-aligned).
    * @return The original buffer, for chaining.
    */
    function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint mask = 256 ** len - 1;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + off + sizeof(buffer length) + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }
}

pragma solidity >0.4.18;

/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for writing to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library Buffer {
    /**
    * @dev Represents a mutable buffer. Buffers have a current value (buf) and
    *      a capacity. The capacity may be longer than the current value, in
    *      which case it can be extended without the need to allocate more memory.
    */
    struct buffer {
        bytes buf;
        uint capacity;
    }

    /**
    * @dev Initializes a buffer with an initial capacity.
    * @param buf The buffer to initialize.
    * @param capacity The number of bytes of space to allocate the buffer.
    * @return The buffer, for chaining.
    */
    function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
        if (capacity % 32 != 0) {
            capacity += 32 - (capacity % 32);
        }
        // Allocate space for the buffer data
        buf.capacity = capacity;
        assembly {
            let ptr := mload(0x40)
            mstore(buf, ptr)
            mstore(ptr, 0)
            mstore(0x40, add(ptr, capacity))
        }
        return buf;
    }

    /**
    * @dev Initializes a new buffer from an existing bytes object.
    *      Changes to the buffer may mutate the original value.
    * @param b The bytes object to initialize the buffer with.
    * @return A new buffer.
    */
    function fromBytes(bytes memory b) internal pure returns(buffer memory) {
        buffer memory buf;
        buf.buf = b;
        buf.capacity = b.length;
        return buf;
    }

    function resize(buffer memory buf, uint capacity) private pure {
        bytes memory oldbuf = buf.buf;
        init(buf, capacity);
        append(buf, oldbuf);
    }

    function max(uint a, uint b) private pure returns(uint) {
        if (a > b) {
            return a;
        }
        return b;
    }

    /**
    * @dev Sets buffer length to 0.
    * @param buf The buffer to truncate.
    * @return The original buffer, for chaining..
    */
    function truncate(buffer memory buf) internal pure returns (buffer memory) {
        assembly {
            let bufptr := mload(buf)
            mstore(bufptr, 0)
        }
        return buf;
    }

    /**
    * @dev Writes a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The start offset to write to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) {
        require(len <= data.length);

        if (off + len + buf.buf.length > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint dest;
        uint src;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Start address = buffer address + offset + sizeof(buffer length)
            dest := add(add(bufptr, 32), off)
            // Update buffer length if we're extending it
            if gt(add(len, off), buflen) {
                mstore(bufptr, add(len, off))
            }
            src := add(data, 32)
        }

        // Copy word-length chunks while possible
        for (; len >= 32; len -= 32) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += 32;
            src += 32;
        }

        // Copy remaining bytes
        uint mask = 256 ** (32 - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }

        return buf;
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @param len The number of bytes to copy.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, len);
    }

    /**
    * @dev Appends a byte string to a buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, data.length);
    }

    /**
    * @dev Writes a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write the byte at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) {
        if (off > buf.capacity) {
            resize(buf, buf.capacity * 2);
        }

        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Length of existing buffer data
            let buflen := mload(bufptr)
            // Address = buffer address + sizeof(buffer length) + off
            let dest := add(add(bufptr, off), 32)
            mstore8(dest, data)
            // Update buffer length if we extended it
            if eq(off, buflen) {
                mstore(bufptr, add(buflen, 1))
            }
        }
        return buf;
    }

    /**
    * @dev Appends a byte to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
        return writeUint8(buf, buf.buf.length, data);
    }

    /**
    * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would
    *      exceed the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (left-aligned).
    * @return The original buffer, for chaining.
    */
    function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, max(buf.capacity, len) * 2);
        }

        uint mask = 256 ** len - 1;
        // Right-align data
        data = data >> (8 * (32 - len));
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + sizeof(buffer length) + off + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }

    /**
    * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the
    *      capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, off, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chhaining.
    */
    function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, bytes32(data), 20);
    }

    /**
    * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param data The data to append.
    * @return The original buffer, for chaining.
    */
    function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
        return write(buf, buf.buf.length, data, 32);
    }

    /**
    * @dev Writes an integer to the buffer. Resizes if doing so would exceed
    *      the capacity of the buffer.
    * @param buf The buffer to append to.
    * @param off The offset to write at.
    * @param data The data to append.
    * @param len The number of bytes to write (right-aligned).
    * @return The original buffer, for chaining.
    */
    function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) {
        if (len + off > buf.capacity) {
            resize(buf, max(buf.capacity, len + off) * 2);
        }

        uint mask = 256 ** len - 1;
        assembly {
            // Memory address of the buffer data
            let bufptr := mload(buf)
            // Address = buffer address + off + sizeof(buffer length) + len
            let dest := add(add(bufptr, off), len)
            mstore(dest, or(and(mload(dest), not(mask)), data))
            // Update buffer length if we extended it
            if gt(add(off, len), mload(bufptr)) {
                mstore(bufptr, add(off, len))
            }
        }
        return buf;
    }
}