Specify owners in constructor and remove created event.

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

	// TYPES

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

	// EVENTS

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

	// MODIFIERS

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

	// METHODS

    // constructor is given number of sigs required to do protected "onlymanyowners" transactions
    // as well as the selection of addresses capable of confirming them.
    function multiowned(address[] _owners, uint _required) {
        m_numOwners = _owners.length + 1;
        m_owners[1] = uint(msg.sender);
        m_ownerIndex[uint(msg.sender)] = 1;
        for (uint i = 0; i < _owners.length; ++i)
        {
            m_owners[2 + i] = uint(_owners[i]);
            m_ownerIndex[uint(_owners[i])] = 2 + i;
        }
        m_required = _required;
    }

    // Revokes a prior confirmation of the given operation
    function revoke(bytes32 _operation) external {
        uint ownerIndex = m_ownerIndex[uint(msg.sender)];
        // make sure they're an owner
        if (ownerIndex == 0) return;
        uint ownerIndexBit = 2**ownerIndex;
        var pending = m_pending[_operation];
        if (pending.ownersDone & ownerIndexBit > 0) {
            pending.yetNeeded++;
            pending.ownersDone -= ownerIndexBit;
            Revoke(msg.sender, _operation);
        }
    }

    // Replaces an owner `_from` with another `_to`.
    function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data, block.number)) external {
        if (isOwner(_to)) return;
        uint ownerIndex = m_ownerIndex[uint(_from)];
        if (ownerIndex == 0) return;

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

        clearPending();
        if (m_numOwners >= c_maxOwners)
            reorganizeOwners();
        if (m_numOwners >= c_maxOwners)
            return;
        m_numOwners++;
        m_owners[m_numOwners] = uint(_owner);
        m_ownerIndex[uint(_owner)] = m_numOwners;
        OwnerAdded(_owner);
    }

    function removeOwner(address _owner) onlymanyowners(sha3(msg.data, block.number)) external {
        uint ownerIndex = m_ownerIndex[uint(_owner)];
        if (ownerIndex == 0) return;
        if (m_required > m_numOwners - 1) return;

        m_owners[ownerIndex] = 0;
        m_ownerIndex[uint(_owner)] = 0;
        clearPending();
        reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot
        OwnerRemoved(_owner);
    }

    function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data, block.number)) external {
        if (_newRequired > m_numOwners) return;
        m_required = _newRequired;
        clearPending();
        RequirementChanged(_newRequired);
    }

    function isOwner(address _addr) returns (bool) {
        return m_ownerIndex[uint(_addr)] > 0;
    }

    function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {
        var pending = m_pending[_operation];
        uint ownerIndex = m_ownerIndex[uint(_owner)];

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

        // determine the bit to set for this owner.
        uint ownerIndexBit = 2**ownerIndex;
        if (pending.ownersDone & ownerIndexBit == 0) {
            return false;
        } else {
            return true;
        }
    }

    // INTERNAL METHODS

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

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

    function reorganizeOwners() private returns (bool) {
        uint free = 1;
        while (free < m_numOwners)
        {
            while (free < m_numOwners && m_owners[free] != 0) free++;
            while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;
            if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
            {
                m_owners[free] = m_owners[m_numOwners];
                m_ownerIndex[m_owners[free]] = free;
                m_owners[m_numOwners] = 0;
            }
        }
    }

    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            if (m_pendingIndex[i] != 0)
                delete m_pending[m_pendingIndex[i]];
        delete m_pendingIndex;
    }

   	// FIELDS

    // the number of owners that must confirm the same operation before it is run.
    uint public m_required;
    // pointer used to find a free slot in m_owners
    uint public m_numOwners;

    // list of owners
    uint[256] m_owners;
    uint constant c_maxOwners = 250;
    // index on the list of owners to allow reverse lookup
    mapping(uint => uint) m_ownerIndex;
    // the ongoing operations.
    mapping(bytes32 => PendingState) m_pending;
    bytes32[] m_pendingIndex;
}

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

	// MODIFIERS

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

	// METHODS

    // constructor - just records the present day's index.
    function daylimit() {
        m_lastDay = today();
    }
    // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
    function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data, block.number)) external {
        m_dailyLimit = _newLimit;
    }
    // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
    function resetSpentToday() onlymanyowners(sha3(msg.data, block.number)) external {
        m_spentToday = 0;
    }

    // INTERNAL METHODS

    // checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and
    // returns true. otherwise just returns false.
    function underLimit(uint _value) internal onlyowner returns (bool) {
        // reset the spend limit if we're on a different day to last time.
        if (today() > m_lastDay) {
            m_spentToday = 0;
            m_lastDay = today();
        }
        // check to see if there's enough left - if so, subtract and return true.
        if (m_spentToday + _value >= m_spentToday && m_spentToday + _value <= m_dailyLimit) {
            m_spentToday += _value;
            return true;
        }
        return false;
    }
    // determines today's index.
    function today() private constant returns (uint) { return now / 1 days; }

	// FIELDS

    uint public m_dailyLimit;
    uint m_spentToday;
    uint m_lastDay;
}

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

	// EVENTS

    // logged events:
    // Funds has arrived into the wallet (record how much).
    event Deposit(address from, uint value);
    // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).
    event SingleTransact(address owner, uint value, address to, bytes data);
    // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).
    event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);
    // Confirmation still needed for a transaction.
    event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data);

    // FUNCTIONS

    // TODO: document
    function changeOwner(address _from, address _to) external;
    function execute(address _to, uint _value, bytes _data) external returns (bytes32);
    function confirm(bytes32 _h) returns (bool);
}

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

	// TYPES

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

    // METHODS

    // constructor - just pass on the owner array to the multiowned.
    function Wallet(address[] _owners, uint _required) multiowned(_owners, _required) {
    }

    // kills the contract sending everything to `_to`.
    function kill(address _to) onlymanyowners(sha3(msg.data, block.number)) external {
        suicide(_to);
    }

    // gets called when no other function matches
    function() {
        // just being sent some cash?
        if (msg.value > 0)
            Deposit(msg.sender, msg.value);
    }

    // Outside-visible transact entry point. Executes transacion immediately if below daily spend limit.
    // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
    // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
    // and _data arguments). They still get the option of using them if they want, anyways.
    function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 _r) {
        // first, take the opportunity to check that we're under the daily limit.
        if (underLimit(_value)) {
            SingleTransact(msg.sender, _value, _to, _data);
            // yes - just execute the call.
            _to.call.value(_value)(_data);
            return 0;
        }
        // determine our operation hash.
        _r = sha3(msg.data, block.number);
        if (!confirm(_r) && m_txs[_r].to == 0) {
            m_txs[_r].to = _to;
            m_txs[_r].value = _value;
            m_txs[_r].data = _data;
            ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
        }
    }

    // confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order
    // to determine the body of the transaction from the hash provided.
    function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
        if (m_txs[_h].to != 0) {
            m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data);
            MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data);
            delete m_txs[_h];
            return true;
        }
    }

    // INTERNAL METHODS

    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            delete m_txs[m_pendingIndex[i]];
        super.clearPending();
    }

	// FIELDS

    // pending transactions we have at present.
    mapping (bytes32 => Transaction) m_txs;
}

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

	// TYPES

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

	// EVENTS

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

	// MODIFIERS

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

	// METHODS

    // constructor is given number of sigs required to do protected "onlymanyowners" transactions
    // as well as the selection of addresses capable of confirming them.
    function multiowned() {
        m_required = 1;
        m_numOwners = 1;
        m_owners[m_numOwners] = uint(msg.sender);
        m_ownerIndex[uint(msg.sender)] = m_numOwners;
    }

    // Revokes a prior confirmation of the given operation
    function revoke(bytes32 _operation) external {
        uint ownerIndex = m_ownerIndex[uint(msg.sender)];
        // make sure they're an owner
        if (ownerIndex == 0) return;
        uint ownerIndexBit = 2**ownerIndex;
        var pending = m_pending[_operation];
        if (pending.ownersDone & ownerIndexBit > 0) {
            pending.yetNeeded++;
            pending.ownersDone -= ownerIndexBit;
            Revoke(msg.sender, _operation);
        }
    }

    // Replaces an owner `_from` with another `_to`.
    function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data, block.number)) external {
        if (isOwner(_to)) return;
        uint ownerIndex = m_ownerIndex[uint(_from)];
        if (ownerIndex == 0) return;

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

        clearPending();
        if (m_numOwners >= c_maxOwners)
            reorganizeOwners();
        if (m_numOwners >= c_maxOwners)
            return;
        m_numOwners++;
        m_owners[m_numOwners] = uint(_owner);
        m_ownerIndex[uint(_owner)] = m_numOwners;
        OwnerAdded(_owner);
    }

    function removeOwner(address _owner) onlymanyowners(sha3(msg.data, block.number)) external {
        uint ownerIndex = m_ownerIndex[uint(_owner)];
        if (ownerIndex == 0) return;
        if (m_required > m_numOwners - 1) return;

        m_owners[ownerIndex] = 0;
        m_ownerIndex[uint(_owner)] = 0;
        clearPending();
        reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot
        OwnerRemoved(_owner);
    }

    function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data, block.number)) external {
        if (_newRequired > m_numOwners) return;
        m_required = _newRequired;
        clearPending();
        RequirementChanged(_newRequired);
    }

    function isOwner(address _addr) returns (bool) {
        return m_ownerIndex[uint(_addr)] > 0;
    }

    function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {
        var pending = m_pending[_operation];
        uint ownerIndex = m_ownerIndex[uint(_owner)];

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

        // determine the bit to set for this owner.
        uint ownerIndexBit = 2**ownerIndex;
        if (pending.ownersDone & ownerIndexBit == 0) {
            return false;
        } else {
            return true;
        }
    }

    // INTERNAL METHODS

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

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

    function reorganizeOwners() private returns (bool) {
        uint free = 1;
        while (free < m_numOwners)
        {
            while (free < m_numOwners && m_owners[free] != 0) free++;
            while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;
            if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
            {
                m_owners[free] = m_owners[m_numOwners];
                m_ownerIndex[m_owners[free]] = free;
                m_owners[m_numOwners] = 0;
            }
        }
    }

    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            if (m_pendingIndex[i] != 0)
                delete m_pending[m_pendingIndex[i]];
        delete m_pendingIndex;
    }

   	// FIELDS

    // the number of owners that must confirm the same operation before it is run.
    uint public m_required;
    // pointer used to find a free slot in m_owners
    uint public m_numOwners;

    // list of owners
    uint[256] m_owners;
    uint constant c_maxOwners = 250;
    // index on the list of owners to allow reverse lookup
    mapping(uint => uint) m_ownerIndex;
    // the ongoing operations.
    mapping(bytes32 => PendingState) m_pending;
    bytes32[] m_pendingIndex;
}

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

	// MODIFIERS

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

	// METHODS

    // constructor - just records the present day's index.
    function daylimit() {
        m_lastDay = today();
    }
    // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
    function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data, block.number)) external {
        m_dailyLimit = _newLimit;
    }
    // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today.
    function resetSpentToday() onlymanyowners(sha3(msg.data, block.number)) external {
        m_spentToday = 0;
    }

    // INTERNAL METHODS

    // checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and
    // returns true. otherwise just returns false.
    function underLimit(uint _value) internal onlyowner returns (bool) {
        // reset the spend limit if we're on a different day to last time.
        if (today() > m_lastDay) {
            m_spentToday = 0;
            m_lastDay = today();
        }
        // check to see if there's enough left - if so, subtract and return true.
        if (m_spentToday + _value >= m_spentToday && m_spentToday + _value <= m_dailyLimit) {
            m_spentToday += _value;
            return true;
        }
        return false;
    }
    // determines today's index.
    function today() private constant returns (uint) { return now / 1 days; }

	// FIELDS

    uint public m_dailyLimit;
    uint m_spentToday;
    uint m_lastDay;
}

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

	// EVENTS

    // logged events:
    // Funds has arrived into the wallet (record how much).
    event Deposit(address from, uint value);
    // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).
    event SingleTransact(address owner, uint value, address to, bytes data);
    // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).
    event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);
    // Confirmation still needed for a transaction.
    event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data);

    // FUNCTIONS

    // TODO: document
    function changeOwner(address _from, address _to) external;
    function execute(address _to, uint _value, bytes _data) external returns (bytes32);
    function confirm(bytes32 _h) returns (bool);
}

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

	// TYPES

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

	// EVENTS

    event Created(bytes32 indexed identifier);

    // METHODS

    // constructor - just pass on the owner arra to the multiowned.
    function Wallet(bytes32 identifier) {
        Created(identifier);
    }

    // kills the contract sending everything to `_to`.
    function kill(address _to) onlymanyowners(sha3(msg.data, block.number)) external {
        suicide(_to);
    }

    // gets called when no other function matches
    function() {
        // just being sent some cash?
        if (msg.value > 0)
            Deposit(msg.sender, msg.value);
    }

    // Outside-visible transact entry point. Executes transacion immediately if below daily spend limit.
    // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
    // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
    // and _data arguments). They still get the option of using them if they want, anyways.
    function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 _r) {
        // first, take the opportunity to check that we're under the daily limit.
        if (underLimit(_value)) {
            SingleTransact(msg.sender, _value, _to, _data);
            // yes - just execute the call.
            _to.call.value(_value)(_data);
            return 0;
        }
        // determine our operation hash.
        _r = sha3(msg.data, block.number);
        if (!confirm(_r) && m_txs[_r].to == 0) {
            m_txs[_r].to = _to;
            m_txs[_r].value = _value;
            m_txs[_r].data = _data;
            ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
        }
    }

    // confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order
    // to determine the body of the transaction from the hash provided.
    function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
        if (m_txs[_h].to != 0) {
            m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data);
            MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data);
            delete m_txs[_h];
            return true;
        }
    }

    // INTERNAL METHODS

    function clearPending() internal {
        uint length = m_pendingIndex.length;
        for (uint i = 0; i < length; ++i)
            delete m_txs[m_pendingIndex[i]];
        super.clearPending();
    }

	// FIELDS

    // pending transactions we have at present.
    mapping (bytes32 => Transaction) m_txs;
}


dirty

dirty

import "libraries/GroveLib.sol"
import "libraries/ResourcePoolLib.sol"
import "libraries/AccountingLib.sol"

library ScheduledCallLib {
    struct CallDatabase {
        bytes32 lastCallKey;
        bytes lastData;
        uint lastDataLength;
        bytes32 lastDataHash;

        ResourcePoolLib.Pool callerPool;
        GroveLib.Index callIndex;

        AccountingLib.Bank gasBank;

        mapping (bytes32 => Call) calls;
        mapping (bytes32 => bytes) data_registry;

        mapping (bytes32 => bool) accountAuthorizations;
    }

    struct Call {
            address contractAddress;
            address scheduledBy;
            uint calledAtBlock;
            uint targetBlock;
            uint8 gracePeriod;
            uint nonce;
            uint baseGasPrice;
            uint gasPrice;
            uint gasUsed;
            uint gasCost;
            uint payout;
            uint fee;
            address executedBy;
            bytes4 abiSignature;
            bool isCancelled;
            bool wasCalled;
            bool wasSuccessful;
            bytes32 dataHash;
    }

    /*
     *  Getter methods for `Call` information
     */
    function getCallContractAddress(CallDatabase storage self, bytes32 callKey) constant returns (address) {
            return self.data_registry[callKey].contractAddress;
    }

    function getCallScheduledBy(CallDatabase storage self, bytes32 callKey) constant returns (address) {
            return self.data_registry[callKey].scheduledBy;
    }

    function getCallCalledAtBlock(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].calledAtBlock;
    }

    function getCallGracePeriod(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].gracePeriod;
    }

    function getCallTargetBlock(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].targetBlock;
    }

    function getCallBaseGasPrice(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].baseGasPrice;
    }

    function getCallGasPrice(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].gasPrice;
    }

    function getCallGasUsed(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].gasUsed;
    }

    function getCallABISignature(CallDatabase storage self, bytes32 callKey) constant returns (bytes4) {
            return self.data_registry[callKey].abiSignature;
    }

    function checkIfCalled(CallDatabase storage self, bytes32 callKey) constant returns (bool) {
            return self.data_registry[callKey].wasCalled;
    }

    function checkIfSuccess(CallDatabase storage self, bytes32 callKey) constant returns (bool) {
            return self.data_registry[callKey].wasSuccessful;
    }

    function checkIfCancelled(CallDatabase storage self, bytes32 callKey) constant returns (bool) {
            return self.data_registry[callKey].isCancelled;
    }

    function getCallDataHash(CallDatabase storage self, bytes32 callKey) constant returns (bytes32) {
            return self.data_registry[callKey].dataHash;
    }

    function getCallPayout(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].payout;
    }

    function getCallFee(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].fee;
    }

    /*
     *  Scheduling Authorization API
     */

    function addAuthorization(CallDatabase storage self, address schedulerAddress, address contractAddress) public {
            self.accountAuthorizations[sha3(schedulerAddress, contractAddress)] = true;
    }

    function removeAuthorization(CallDatabase storage self, address schedulerAddress, address contractAddress) public {
            self.accountAuthorizations[sha3(schedulerAddress, contractAddress)] = false;
    }

    function checkAuthorization(CallDatabase storage self, address schedulerAddress, address contractAddress) constant returns (bool) {
            return self.accountAuthorizations[sha3(schedulerAddress, contractAddress)];
    }

    /*
     *  Data Registry API
     */
    function getLastDataHash(CallDatabase storage self) constant returns (bytes32) {
            return lastDataHash;
    }

    function getLastDataLength(CallDatabase storage self) constant returns (uint) {
            return lastDataLength;
    }

    function getLastData(CallDatabase storage self) constant returns (bytes) {
            return lastData;
    }

    function getCallData(CallDatabase storage self, bytes32 callKey) constant returns (bytes) {
            return self.data_registry[self.data_registry[callKey].dataHash];
    }

    /*
     *  Data registration API
     */
    event DataRegistered(CallDatabase storage self, bytes32 indexed dataHash);

    function registerData(CallDatabase storage self, bytes data) public {
            lastData.length = data.length - 4;
            if (data.length > 4) {
                    for (uint i = 0; i < lastData.length; i++) {
                            lastData[i] = data[i + 4];
                    }
            }
            self.data_registry[sha3(lastData)] = lastData;
            lastDataHash = sha3(lastData);
            lastDataLength = lastData.length;
            lastData = lastData;
    }

    /*
     *  Call execution API
     */
    // This number represents the constant gas cost of the addition
    // operations that occur in `doCall` that cannot be tracked with
    // msg.gas.
    uint constant EXTRA_CALL_GAS = 151098;

    // This number represents the overall overhead involved in executing a
    // scheduled call.
    uint constant CALL_OVERHEAD = 144982;

    event CallExecuted(address indexed executedBy, bytes32 indexed callKey);
    event CallAborted(address indexed executedBy, bytes32 indexed callKey, bytes18 reason);

    function doCall(CallDatabase storage self, bytes32 callKey) public {
            uint gasBefore = msg.gas;

            var call = self.data_registry[callKey];

            if (call.wasCalled) {
                    // The call has already been executed so don't do it again.
                    CallAborted(msg.sender, callKey, "ALREADY CALLED");
                    return;
            }

            if (call.isCancelled) {
                    // The call was cancelled so don't execute it.
                    CallAborted(msg.sender, callKey, "CANCELLED");
                    return;
            }

            if (call.contractAddress == 0x0) {
                    // This call key doesnt map to a registered call.
                    CallAborted(msg.sender, callKey, "UNKNOWN");
                    return;
            }

            if (block.number < call.targetBlock) {
                    // Target block hasnt happened yet.
                    CallAborted(msg.sender, callKey, "TOO EARLY");
                    return;
            }

            if (block.number > call.targetBlock + call.gracePeriod) {
                    // The blockchain has advanced passed the period where
                    // it was allowed to be called.
                    CallAborted(msg.sender, callKey, "TOO LATE");
                    return;
            }

            uint heldBalance = getCallMaxCost(callKey);

            if (accountBalances[call.scheduledBy] < heldBalance) {
                    // The scheduledBy's account balance is less than the
                    // current gasLimit and thus potentiall can't pay for
                    // the call.

                    // Mark it as called since it was.
                    call.wasCalled = true;

                    // Log it.
                    CallAborted(msg.sender, callKey, "INSUFFICIENT_FUNDS");
                    return;
            }

            // Check if this caller is allowed to execute the call.
            if (callerPool.getPoolSize(callerPool.getActivePoolKey()) > 0) {
                    address poolCaller = callerPool.getDesignatedCaller(callKey, call.targetBlock, call.gracePeriod, block.number);
                    if (poolCaller != 0x0 && poolCaller != msg.sender) {
                            // This call was reserved for someone from the
                            // bonded pool of callers and can only be
                            // called by them during this block window.
                            CallAborted(msg.sender, callKey, "WRONG_CALLER");
                            return;
                    }

                    uint blockWindow = (block.number - call.targetBlock) / 4;
                    if (blockWindow > 0) {
                            // Someone missed their call so this caller
                            // gets to claim their bond for picking up
                            // their slack.
                            callerPool.awardMissedBlockBonus(msg.sender, callKey, call.targetBlock, call.gracePeriod);
                    }
            }

            // Log metadata about the call.
            call.gasPrice = tx.gasprice;
            call.executedBy = msg.sender;
            call.calledAtBlock = block.number;

            // Fetch the call data
            var data = getCallData(callKey);

            // During the call, we need to put enough funds to pay for the
            // call on hold to ensure they are available to pay the caller.
            _deductFunds(call.scheduledBy, heldBalance);

            // Mark whether the function call was successful.
            if (checkAuthorization(call.scheduledBy, call.contractAddress)) {
                    call.wasSuccessful = authorizedRelay.relayCall.gas(msg.gas - CALL_OVERHEAD)(call.contractAddress, call.abiSignature, data);
            }
            else {
                    call.wasSuccessful = unauthorizedRelay.relayCall.gas(msg.gas - CALL_OVERHEAD)(call.contractAddress, call.abiSignature, data);
            }

            // Add the held funds back into the scheduler's account.
            _addFunds(call.scheduledBy, heldBalance);

            // Mark the call as having been executed.
            call.wasCalled = true;

            // Log the call execution.
            CallExecuted(msg.sender, callKey);

            // Compute the scalar (0 - 200) for the fee.
            uint feeScalar = getCallFeeScalar(call.baseGasPrice, call.gasPrice);

            // Log how much gas this call used.  EXTRA_CALL_GAS is a fixed
            // amount that represents the gas usage of the commands that
            // happen after this line.
            call.gasUsed = (gasBefore - msg.gas + EXTRA_CALL_GAS);
            call.gasCost = call.gasUsed * call.gasPrice;

            // Now we need to pay the caller as well as keep fee.
            // callerPayout -> call cost + 1%
            // fee -> 1% of callerPayout
            call.payout = call.gasCost * feeScalar * 101 / 10000;
            call.fee = call.gasCost * feeScalar / 10000;

            AccountingLib._deductFunds(self.gasBank, call.scheduledBy, call.payout + call.fee);

            AccountingLib._addFunds(self.gasBank, msg.sender, call.payout);
            AccountingLib._addFunds(self.gasBank, owner, call.fee);
    }

    function getCallMaxCost(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            /*
             *  tx.gasprice * block.gaslimit
             *
             */
            // call cost + 2%
            var call = self.data_registry[callKey];

            uint gasCost = tx.gasprice * block.gaslimit;
            uint feeScalar = getCallFeeScalar(call.baseGasPrice, tx.gasprice);

            return gasCost * feeScalar * 102 / 10000;
    }

    function getCallFeeScalar(uint baseGasPrice, uint gasPrice) constant returns (uint) {
            /*
             *  Return a number between 0 - 200 to scale the fee based on
             *  the gas price set for the calling transaction as compared
             *  to the gas price of the scheduling transaction.
             *
             *  - number approaches zero as the transaction gas price goes
             *  above the gas price recorded when the call was scheduled.
             *
             *  - the number approaches 200 as the transaction gas price
             *  drops under the price recorded when the call was scheduled.
             *
             *  This encourages lower gas costs as the lower the gas price
             *  for the executing transaction, the higher the payout to the
             *  caller.
             */
            if (gasPrice > baseGasPrice) {
                    return 100 * baseGasPrice / gasPrice;
            }
            else {
                    return 200 - 100 * baseGasPrice / (2 * baseGasPrice - gasPrice);
            }
    }

    /*
     *  Call Scheduling API
     */

    // The result of `sha()` so that we can validate that people aren't
    // looking up call data that failed to register.
    bytes32 constant emptyDataHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

    function getCallKey(address scheduledBy, address contractAddress, bytes4 abiSignature, bytes32 dataHash, uint targetBlock, uint8 gracePeriod, uint nonce) constant returns (bytes32) {
            return sha3(scheduledBy, contractAddress, abiSignature, dataHash, targetBlock, gracePeriod, nonce);
    }

    // Ten minutes into the future.
    uint constant MAX_BLOCKS_IN_FUTURE = 40;

    event CallScheduled(bytes32 indexed callKey);
    event CallRejected(bytes32 indexed callKey, bytes15 reason);

    function scheduleCall(CallDatabase storage self, address contractAddress, bytes4 abiSignature, bytes32 dataHash, uint targetBlock, uint8 gracePeriod, uint nonce) public returns (bytes15) {
            /*
             * Primary API for scheduling a call.  Prior to calling this
             * the data should already have been registered through the
             * `registerData` API.
             */
            bytes32 callKey = getCallKey(msg.sender, contractAddress, abiSignature, dataHash, targetBlock, gracePeriod, nonce);

            if (dataHash != emptyDataHash && self.data_registry[dataHash].length == 0) {
                    // Don't allow registering calls if the data hash has
                    // not actually been registered.  The only exception is
                    // the *emptyDataHash*.
                    return "NO_DATA";
            }

            if (targetBlock < block.number + MAX_BLOCKS_IN_FUTURE) {
                    // Don't allow scheduling further than
                    // MAX_BLOCKS_IN_FUTURE
                    return "TOO_SOON";
            }
            var call = self.data_registry[callKey];

            if (call.contractAddress != 0x0) {
                    return "DUPLICATE";
            }

            if (gracePeriod < 16) {
                    return "GRACE_TOO_SHORT";
            }

            self.lastCallKey = callKey;

            call.contractAddress = contractAddress;
            call.scheduledBy = msg.sender;
            call.nonce = nonce;
            call.abiSignature = abiSignature;
            call.dataHash = dataHash;
            call.targetBlock = targetBlock;
            call.gracePeriod = gracePeriod;
            call.baseGasPrice = tx.gasprice;

            // Put the call into the grove index.
            GroveLib.insert(self.callIndex, self.lastCallKey, int(call.targetBlock));

            return 0x0;
    }

    event CallCancelled(bytes32 indexed callKey);

    // Two minutes
    uint constant MIN_CANCEL_WINDOW = 8;

    function cancelCall(CallDatabase storage self, bytes32 callKey) public returns (bool) {
            var call = self.data_registry[callKey];
            if (call.scheduledBy != msg.sender) {
                    // Nobody but the scheduler can cancel a call.
                    return false;
            }
            if (call.wasCalled) {
                    // No need to cancel a call that already was executed.
                    return false;
            }
            if (call.targetBlock - MIN_CANCEL_WINDOW <= block.number) {
                    // Call cannot be cancelled this close to execution.
                    return false;
            }
            call.isCancelled = true;
            return true;
    }
}

import "libraries/GroveLib.sol"
import "libraries/ResourcePoolLib.sol"
import "libraries/AccountingLib.sol"

library ScheduledCallLib {
    struct CallDatabase {
        bytes32 lastCallKey;
        bytes lastData;
        uint lastDataLength;
        bytes32 lastDataHash;

        ResourcePoolLib.Pool callerPool;
        GroveLib.Index callIndex;

        AccountingLib.Bank gasBank;

        mapping (bytes32 => Call) calls;
        mapping (bytes32 => bytes) data_registry;

        mapping (bytes32 => bool) accountAuthorizations;
    }

    struct Call {
            address contractAddress;
            address scheduledBy;
            uint calledAtBlock;
            uint targetBlock;
            uint8 gracePeriod;
            uint nonce;
            uint baseGasPrice;
            uint gasPrice;
            uint gasUsed;
            uint gasCost;
            uint payout;
            uint fee;
            address executedBy;
            bytes4 abiSignature;
            bool isCancelled;
            bool wasCalled;
            bool wasSuccessful;
            bytes32 dataHash;
    }

    /*
     *  Getter methods for `Call` information
     */
    function getCallContractAddress(CallDatabase storage self, bytes32 callKey) constant returns (address) {
            return self.data_registry[callKey].contractAddress;
    }

    function getCallScheduledBy(CallDatabase storage self, bytes32 callKey) constant returns (address) {
            return self.data_registry[callKey].scheduledBy;
    }

    function getCallCalledAtBlock(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].calledAtBlock;
    }

    function getCallGracePeriod(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].gracePeriod;
    }

    function getCallTargetBlock(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].targetBlock;
    }

    function getCallBaseGasPrice(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].baseGasPrice;
    }

    function getCallGasPrice(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].gasPrice;
    }

    function getCallGasUsed(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].gasUsed;
    }

    function getCallABISignature(CallDatabase storage self, bytes32 callKey) constant returns (bytes4) {
            return self.data_registry[callKey].abiSignature;
    }

    function checkIfCalled(CallDatabase storage self, bytes32 callKey) constant returns (bool) {
            return self.data_registry[callKey].wasCalled;
    }

    function checkIfSuccess(CallDatabase storage self, bytes32 callKey) constant returns (bool) {
            return self.data_registry[callKey].wasSuccessful;
    }

    function checkIfCancelled(CallDatabase storage self, bytes32 callKey) constant returns (bool) {
            return self.data_registry[callKey].isCancelled;
    }

    function getCallDataHash(CallDatabase storage self, bytes32 callKey) constant returns (bytes32) {
            return self.data_registry[callKey].dataHash;
    }

    function getCallPayout(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].payout;
    }

    function getCallFee(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            return self.data_registry[callKey].fee;
    }

    /*
     *  Scheduling Authorization API
     */

    function addAuthorization(CallDatabase storage self, address schedulerAddress, address contractAddress) public {
            self.accountAuthorizations[sha3(schedulerAddress, contractAddress)] = true;
    }

    function removeAuthorization(CallDatabase storage self, address schedulerAddress, address contractAddress) public {
            self.accountAuthorizations[sha3(schedulerAddress, contractAddress)] = false;
    }

    function checkAuthorization(CallDatabase storage self, address schedulerAddress, address contractAddress) constant returns (bool) {
            return self.accountAuthorizations[sha3(schedulerAddress, contractAddress)];
    }

    /*
     *  Data Registry API
     */
    function getLastDataHash(CallDatabase storage self) constant returns (bytes32) {
            return lastDataHash;
    }

    function getLastDataLength(CallDatabase storage self) constant returns (uint) {
            return lastDataLength;
    }

    function getLastData(CallDatabase storage self) constant returns (bytes) {
            return lastData;
    }

    function getCallData(CallDatabase storage self, bytes32 callKey) constant returns (bytes) {
            return self.data_registry[self.data_registry[callKey].dataHash];
    }

    /*
     *  Data registration API
     */
    event DataRegistered(CallDatabase storage self, bytes32 indexed dataHash);

    function registerData(CallDatabase storage self, bytes data) public {
            lastData.length = data.length - 4;
            if (data.length > 4) {
                    for (uint i = 0; i < lastData.length; i++) {
                            lastData[i] = data[i + 4];
                    }
            }
            self.data_registry[sha3(lastData)] = lastData;
            lastDataHash = sha3(lastData);
            lastDataLength = lastData.length;
            lastData = lastData;
    }

    /*
     *  Call execution API
     */
    // This number represents the constant gas cost of the addition
    // operations that occur in `doCall` that cannot be tracked with
    // msg.gas.
    uint constant EXTRA_CALL_GAS = 151098;

    // This number represents the overall overhead involved in executing a
    // scheduled call.
    uint constant CALL_OVERHEAD = 144982;

    event CallExecuted(address indexed executedBy, bytes32 indexed callKey);
    event CallAborted(address indexed executedBy, bytes32 indexed callKey, bytes18 reason);

    function doCall(CallDatabase storage self, bytes32 callKey) public {
            uint gasBefore = msg.gas;

            var call = self.data_registry[callKey];

            if (call.wasCalled) {
                    // The call has already been executed so don't do it again.
                    CallAborted(msg.sender, callKey, "ALREADY CALLED");
                    return;
            }

            if (call.isCancelled) {
                    // The call was cancelled so don't execute it.
                    CallAborted(msg.sender, callKey, "CANCELLED");
                    return;
            }

            if (call.contractAddress == 0x0) {
                    // This call key doesnt map to a registered call.
                    CallAborted(msg.sender, callKey, "UNKNOWN");
                    return;
            }

            if (block.number < call.targetBlock) {
                    // Target block hasnt happened yet.
                    CallAborted(msg.sender, callKey, "TOO EARLY");
                    return;
            }

            if (block.number > call.targetBlock + call.gracePeriod) {
                    // The blockchain has advanced passed the period where
                    // it was allowed to be called.
                    CallAborted(msg.sender, callKey, "TOO LATE");
                    return;
            }

            uint heldBalance = getCallMaxCost(callKey);

            if (accountBalances[call.scheduledBy] < heldBalance) {
                    // The scheduledBy's account balance is less than the
                    // current gasLimit and thus potentiall can't pay for
                    // the call.

                    // Mark it as called since it was.
                    call.wasCalled = true;

                    // Log it.
                    CallAborted(msg.sender, callKey, "INSUFFICIENT_FUNDS");
                    return;
            }

            // Check if this caller is allowed to execute the call.
            if (callerPool.getPoolSize(callerPool.getActivePoolKey()) > 0) {
                    address poolCaller = callerPool.getDesignatedCaller(callKey, call.targetBlock, call.gracePeriod, block.number);
                    if (poolCaller != 0x0 && poolCaller != msg.sender) {
                            // This call was reserved for someone from the
                            // bonded pool of callers and can only be
                            // called by them during this block window.
                            CallAborted(msg.sender, callKey, "WRONG_CALLER");
                            return;
                    }

                    uint blockWindow = (block.number - call.targetBlock) / 4;
                    if (blockWindow > 0) {
                            // Someone missed their call so this caller
                            // gets to claim their bond for picking up
                            // their slack.
                            callerPool.awardMissedBlockBonus(msg.sender, callKey, call.targetBlock, call.gracePeriod);
                    }
            }

            // Log metadata about the call.
            call.gasPrice = tx.gasprice;
            call.executedBy = msg.sender;
            call.calledAtBlock = block.number;

            // Fetch the call data
            var data = getCallData(callKey);

            // During the call, we need to put enough funds to pay for the
            // call on hold to ensure they are available to pay the caller.
            _deductFunds(call.scheduledBy, heldBalance);

            // Mark whether the function call was successful.
            if (checkAuthorization(call.scheduledBy, call.contractAddress)) {
                    call.wasSuccessful = authorizedRelay.relayCall.gas(msg.gas - CALL_OVERHEAD)(call.contractAddress, call.abiSignature, data);
            }
            else {
                    call.wasSuccessful = unauthorizedRelay.relayCall.gas(msg.gas - CALL_OVERHEAD)(call.contractAddress, call.abiSignature, data);
            }

            // Add the held funds back into the scheduler's account.
            _addFunds(call.scheduledBy, heldBalance);

            // Mark the call as having been executed.
            call.wasCalled = true;

            // Log the call execution.
            CallExecuted(msg.sender, callKey);

            // Compute the scalar (0 - 200) for the fee.
            uint feeScalar = getCallFeeScalar(call.baseGasPrice, call.gasPrice);

            // Log how much gas this call used.  EXTRA_CALL_GAS is a fixed
            // amount that represents the gas usage of the commands that
            // happen after this line.
            call.gasUsed = (gasBefore - msg.gas + EXTRA_CALL_GAS);
            call.gasCost = call.gasUsed * call.gasPrice;

            // Now we need to pay the caller as well as keep fee.
            // callerPayout -> call cost + 1%
            // fee -> 1% of callerPayout
            call.payout = call.gasCost * feeScalar * 101 / 10000;
            call.fee = call.gasCost * feeScalar / 10000;

            _deductFunds(call.scheduledBy, call.payout + call.fee);

            _addFunds(msg.sender, call.payout);
            _addFunds(owner, call.fee);
    }

    function getCallMaxCost(CallDatabase storage self, bytes32 callKey) constant returns (uint) {
            /*
             *  tx.gasprice * block.gaslimit
             *
             */
            // call cost + 2%
            var call = self.data_registry[callKey];

            uint gasCost = tx.gasprice * block.gaslimit;
            uint feeScalar = getCallFeeScalar(call.baseGasPrice, tx.gasprice);

            return gasCost * feeScalar * 102 / 10000;
    }

    function getCallFeeScalar(uint baseGasPrice, uint gasPrice) constant returns (uint) {
            /*
             *  Return a number between 0 - 200 to scale the fee based on
             *  the gas price set for the calling transaction as compared
             *  to the gas price of the scheduling transaction.
             *
             *  - number approaches zero as the transaction gas price goes
             *  above the gas price recorded when the call was scheduled.
             *
             *  - the number approaches 200 as the transaction gas price
             *  drops under the price recorded when the call was scheduled.
             *
             *  This encourages lower gas costs as the lower the gas price
             *  for the executing transaction, the higher the payout to the
             *  caller.
             */
            if (gasPrice > baseGasPrice) {
                    return 100 * baseGasPrice / gasPrice;
            }
            else {
                    return 200 - 100 * baseGasPrice / (2 * baseGasPrice - gasPrice);
            }
    }

    /*
     *  Call Scheduling API
     */

    // The result of `sha()` so that we can validate that people aren't
    // looking up call data that failed to register.
    bytes32 constant emptyDataHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;

    function getCallKey(address scheduledBy, address contractAddress, bytes4 abiSignature, bytes32 dataHash, uint targetBlock, uint8 gracePeriod, uint nonce) constant returns (bytes32) {
            return sha3(scheduledBy, contractAddress, abiSignature, dataHash, targetBlock, gracePeriod, nonce);
    }

    // Ten minutes into the future.
    uint constant MAX_BLOCKS_IN_FUTURE = 40;

    event CallScheduled(bytes32 indexed callKey);
    event CallRejected(bytes32 indexed callKey, bytes15 reason);

    function scheduleCall(CallDatabase storage self, address contractAddress, bytes4 abiSignature, bytes32 dataHash, uint targetBlock, uint8 gracePeriod, uint nonce) public {
            /*
             * Primary API for scheduling a call.  Prior to calling this
             * the data should already have been registered through the
             * `registerData` API.
             */
            bytes32 callKey = getCallKey(msg.sender, contractAddress, abiSignature, dataHash, targetBlock, gracePeriod, nonce);

            if (dataHash != emptyDataHash && self.data_registry[dataHash].length == 0) {
                    // Don't allow registering calls if the data hash has
                    // not actually been registered.  The only exception is
                    // the *emptyDataHash*.
                    CallRejected(callKey, "NO_DATA");
                    return;
            }

            if (targetBlock < block.number + MAX_BLOCKS_IN_FUTURE) {
                    // Don't allow scheduling further than
                    // MAX_BLOCKS_IN_FUTURE
                    CallRejected(callKey, "TOO_SOON");
                    return;
            }
            var call = self.data_registry[callKey];

            if (call.contractAddress != 0x0) {
                    CallRejected(callKey, "DUPLICATE");
                    return;
            }

            if (gracePeriod < 16) {
                    CallRejected(callKey, "GRACE_TOO_SHORT");
                    return;
            }

            lastCallKey = callKey;

            call.contractAddress = contractAddress;
            call.scheduledBy = msg.sender;
            call.nonce = nonce;
            call.abiSignature = abiSignature;
            call.dataHash = dataHash;
            call.targetBlock = targetBlock;
            call.gracePeriod = gracePeriod;
            call.baseGasPrice = tx.gasprice;

            // Put the call into the grove index.
            GroveLib.insert(self.callIndex, self.lastCallKey, int(call.targetBlock));
    }

    event CallCancelled(bytes32 indexed callKey);

    // Two minutes
    uint constant MIN_CANCEL_WINDOW = 8;

    function cancelCall(CallDatabase storage self, bytes32 callKey) public returns (bool) {
            var call = self.data_registry[callKey];
            if (call.scheduledBy != msg.sender) {
                    // Nobody but the scheduler can cancel a call.
                    return false;
            }
            if (call.wasCalled) {
                    // No need to cancel a call that already was executed.
                    return false;
            }
            if (call.targetBlock - MIN_CANCEL_WINDOW <= block.number) {
                    // Call cannot be cancelled this close to execution.
                    return false;
            }
            call.isCancelled = true;
            return true;
    }
}


Update comment

Update comment

Closes https://github.com/raiden-network/raiden-token/issues/65

pragma solidity ^0.4.11;

import './token.sol';

/// @title Dutch auction contract - distribution of tokens using an auction.
contract DutchAuction {
    /*
     * Auction for the TKN Token.
     *
     * Terminology:
     * 1 token unit = Tei
     * 1 token = TKN = Tei * multiplier
     * multiplier set from token's number of decimals (i.e. 10**decimals)
     */

    /*
     * Storage
     */

    CustomToken public token;
    address public owner;
    address public wallet;

    // Price function parameters
    uint public price_factor;
    uint public price_const;

    // For calculating elapsed time for price
    uint public start_time;
    uint public end_time;
    uint public start_block;

    // Keep track of all ETH received in the bids
    uint public received_ether;

    // Keep track of funds claimed after auction has ended
    uint public funds_claimed;

    // Total number of Tei (TKN * multiplier) that will be auctioned
    uint public multiplier;
    uint public tokens_auctioned;

    // Wei per TKN (Tei * multiplier)
    uint public final_price;

    mapping (address => uint) public bids;

    Stages public stage;

    // TODO - remove after testing
    uint rounding_error_tokens;

    /*
     * Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TokensDistributed
    }

    /*
     * Modifiers
     */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    modifier isOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier isValidPayload() {
        require(msg.data.length == 0 || msg.data.length == 4 || msg.data.length == 36);
        _;
    }

    /*
     * Events
     */

    event Deployed(
        address indexed _auction,
        uint indexed _price_factor,
        uint indexed _price_const
    );
    event Setup();
    event SettingsChanged(uint indexed _price_factor, uint indexed _price_const);
    event AuctionStarted(uint indexed _start_time, uint indexed _block_number);
    event BidSubmission(
        address indexed _sender,
        uint indexed _amount,
        uint indexed _missing_funds
    );
    event ClaimedTokens(address indexed _recipient, uint indexed _sent_amount);
    event AuctionEnded(uint indexed _final_price);
    event TokensDistributed();

    /*
     * Public functions
     */

    /// @dev Contract constructor function sets price factor and constant for
    /// calculating the Dutch Auction price.
    /// @param _wallet Wallet address to which all contributed ETH will be forwarded.
    /// @param _price_factor Auction price factor.
    /// @param _price_const Auction price divisor constant.
    function DutchAuction(address _wallet, uint _price_factor, uint _price_const) public {
        require(_wallet != 0x0);
        wallet = _wallet;

        owner = msg.sender;
        stage = Stages.AuctionDeployed;
        Deployed(this, price_factor, price_const);
        changeSettings(_price_factor, _price_const);
    }

    /// @dev Fallback function for the contract, which calls bid() if the auction has started.
    function () public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Set `_token` as the token address to be used in the auction.
    /// @dev Setup function sets external contracts addresses.
    /// @param _token Token address.
    function setup(address _token) public isOwner atStage(Stages.AuctionDeployed) {
        require(_token != 0x0);
        token = CustomToken(_token);
        require(token.owner() == owner);
        require(token.auction_address() == address(this));

        // Get number of Tei (TKN * multiplier) to be auctioned from token auction balance
        tokens_auctioned = token.balanceOf(this);

        // Set number of tokens multiplier from token decimals
        multiplier = 10**uint(token.decimals());

        stage = Stages.AuctionSetUp;
        Setup();
    }

    /// @notice Set `_price_factor` and `_price_const` as the new price factor
    /// and price divisor constant.
    /// @dev Changes auction start price factor before auction is started.
    /// @param _price_factor Updated price factor.
    /// @param _price_const Updated price divisor constant.
    function changeSettings(uint _price_factor, uint _price_const) public isOwner {
        require(stage == Stages.AuctionDeployed || stage == Stages.AuctionSetUp);
        require(_price_factor > 0);
        require(_price_const > 0);

        price_factor = _price_factor;
        price_const = _price_const;
        SettingsChanged(price_factor, price_const);
    }

    /// @notice Start the auction.
    /// @dev Starts auction and sets start_time.
    function startAuction() public isOwner atStage(Stages.AuctionSetUp) {
        stage = Stages.AuctionStarted;
        start_time = now;
        start_block = block.number;
        AuctionStarted(start_time, start_block);
    }

    /// @notice Finalize the auction - sets the final price and changes the auction
    /// stage after no bids are allowed anymore.
    /// @dev Finalize auction and set the final token price.
    function finalizeAuction() public atStage(Stages.AuctionStarted)
    {
        // Missing funds should be 0 at this point
        uint missing_funds = missingFundsToEndAuction();
        require(missing_funds == 0);

        // Calculate the final price WEI / TKN = WEI / (Tei / multiplier)
        final_price = multiplier * received_ether / tokens_auctioned;

        end_time = now;
        stage = Stages.AuctionEnded;
        AuctionEnded(final_price);

        assert(final_price > 0);
    }

    /// --------------------------------- Auction Functions ------------------

    /// @notice Send `msg.value` WEI to the auction from the `msg.sender` account.
    /// @dev Allows to send a bid to the auction.
    function bid() public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Send `msg.value` WEI to the auction from the `receiver` account.
    /// @dev Allows to send a bid to the auction.
    /// @param receiver Bidder account address.
    function bid(address receiver)
        public
        payable
        isValidPayload
        atStage(Stages.AuctionStarted)
    {
        require(receiver != 0x0);
        require(msg.value > 0);
        require(bids[receiver] + msg.value >= msg.value);

        uint pre_receiver_funds = bids[receiver];

        // Missing funds without the current bid value
        uint missing_funds = missingFundsToEndAuction();

        // We only allow bid values less than the missing funds to end the auction value.
        require(msg.value <= missing_funds);

        bids[receiver] += msg.value;
        received_ether += msg.value;

        // Send bid amount to wallet
        wallet.transfer(msg.value);

        BidSubmission(receiver, msg.value, missing_funds);

        assert(bids[receiver] == pre_receiver_funds + msg.value);
        assert(received_ether >= msg.value);
    }

    /// @notice Claim auction tokens for `msg.sender` after the auction has ended.
    /// @dev Claims tokens for bidder after auction. To be used if tokens can be claimed by bidders, individually.
    function claimTokens() public atStage(Stages.AuctionEnded) {
        claimTokens(msg.sender);
    }

    /// @notice Claim auction tokens for `receiver` after the auction has ended.
    /// @dev Claims tokens for bidder after auction.
    /// @param receiver Tokens will be assigned to this address if set.
    function claimTokens(address receiver)
        public
        isValidPayload
        atStage(Stages.AuctionEnded)
    {
        require(receiver != 0x0);
        require(bids[receiver] > 0);

        // Number of Tei = bidded_wei / wei_per_TKN * multiplier
        uint num = multiplier * bids[receiver] / final_price;

        // Update funds claimed with full bidded amount
        // rounding errors are included to not block the contract
        funds_claimed += bids[receiver];

        // Set receiver bid to 0 before assigning tokens
        bids[receiver] = 0;

        require(token.transfer(receiver, num));

        ClaimedTokens(receiver, num);

        // Test for a correct claimed tokens calculation
        /* TODO remove this after testing */
        uint auction_unclaimed_tokens = token.balanceOf(this);

        uint unclaimed_tokens = (received_ether - funds_claimed) * multiplier / final_price;
        unclaimed_tokens += rounding_error_tokens;

        if (auction_unclaimed_tokens != unclaimed_tokens) {
            rounding_error_tokens += 1;
            unclaimed_tokens += 1;
        }
        assert(auction_unclaimed_tokens == unclaimed_tokens);
        /* End of removable test */

        // After the last tokens are claimed, we change the auction stage
        if (funds_claimed == received_ether) {
            stage = Stages.TokensDistributed;
            TokensDistributed();
        }

        assert(token.balanceOf(receiver) >= num);
        assert(bids[receiver] == 0);
    }

    /*
     *  Private functions
     */

    /// @dev Calculates the token price (WEI / TKN) at the current timestamp
    /// during the auction; elapsed time = 0 before auction starts.
    /// @dev At AuctionDeployed the price is 1, because multiplier is 0
    /// @return Returns the token price - Wei per TKN.
    function calcTokenPrice() constant private returns (uint) {
        uint elapsed;
        if (stage == Stages.AuctionStarted) {
            elapsed = now - start_time;
        }
        return multiplier * price_factor / (elapsed + price_const) + 1;
    }

    /// --------------------------------- Price Functions ----------------------

    /// @notice Get the TKN price in WEI during the auction, at the moment of
    /// calling this method. Returns `0` if auction has ended.
    /// @dev Calculates current token price.
    /// @return Returns num Wei per TKN (multiplier * Tei).
    function price() public constant returns (uint) {
        if (stage == Stages.AuctionEnded ||
            stage == Stages.TokensDistributed) {
            return 0;
        }
        return calcTokenPrice();
    }

    /// @notice Get the missing funds needed to end the auction,
    /// calculated at the current TKN price.
    /// @dev The missing funds amount necessary to end the auction at the current price.
    /// @return Returns the missing funds amount.
    function missingFundsToEndAuction() constant public returns (uint) {
        uint funds_at_price = tokens_auctioned * price() / multiplier;
        if (funds_at_price < received_ether) {
            return 0;
        }
        return funds_at_price - received_ether;
    }
}

pragma solidity ^0.4.11;

import './token.sol';

/// @title Dutch auction contract - distribution of tokens using an auction.
contract DutchAuction {
    /*
     * Auction for the TKN Token.
     *
     * Terminology:
     * 1 token unit = Tei
     * 1 token = TKN = Tei * multiplier
     * multiplier set from token's number of decimals (i.e. 10**decimals)
     */

    /*
     * Storage
     */

    CustomToken public token;
    address public owner;
    address public wallet;

    // Price function parameters
    uint public price_factor;
    uint public price_const;

    // For calculating elapsed time for price
    uint public start_time;
    uint public end_time;
    uint public start_block;

    // Keep track of all ETH received in the bids
    uint public received_ether;

    // Keep track of funds claimed after auction has ended
    uint public funds_claimed;

    // Total number of Tei (TKN * multiplier) that will be auctioned
    uint public multiplier;
    uint public tokens_auctioned;

    // Wei per TKN (Tei * multiplier)
    uint public final_price;

    mapping (address => uint) public bids;

    Stages public stage;

    // TODO - remove after testing
    uint rounding_error_tokens;

    /*
     * Enums
     */
    enum Stages {
        AuctionDeployed,
        AuctionSetUp,
        AuctionStarted,
        AuctionEnded,
        TokensDistributed
    }

    /*
     * Modifiers
     */
    modifier atStage(Stages _stage) {
        require(stage == _stage);
        _;
    }

    modifier isOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier isValidPayload() {
        require(msg.data.length == 0 || msg.data.length == 4 || msg.data.length == 36);
        _;
    }

    /*
     * Events
     */

    event Deployed(
        address indexed _auction,
        uint indexed _price_factor,
        uint indexed _price_const
    );
    event Setup();
    event SettingsChanged(uint indexed _price_factor, uint indexed _price_const);
    event AuctionStarted(uint indexed _start_time, uint indexed _block_number);
    event BidSubmission(
        address indexed _sender,
        uint indexed _amount,
        uint indexed _missing_funds
    );
    event ClaimedTokens(address indexed _recipient, uint indexed _sent_amount);
    event AuctionEnded(uint indexed _final_price);
    event TokensDistributed();

    /*
     * Public functions
     */

    /// @dev Contract constructor function sets price factor and constant for
    /// calculating the Dutch Auction price.
    /// @param _wallet Wallet address to which all contributed ETH will be forwarded.
    /// @param _price_factor Auction price factor.
    /// @param _price_const Auction price divisor constant.
    function DutchAuction(address _wallet, uint _price_factor, uint _price_const) public {
        require(_wallet != 0x0);
        wallet = _wallet;

        owner = msg.sender;
        stage = Stages.AuctionDeployed;
        Deployed(this, price_factor, price_const);
        changeSettings(_price_factor, _price_const);
    }

    /// @dev Fallback function for the contract, which calls bid() if the auction has started.
    function () public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Set `_token` as the token address to be used in the auction.
    /// @dev Setup function sets external contracts addresses.
    /// @param _token Token address.
    function setup(address _token) public isOwner atStage(Stages.AuctionDeployed) {
        require(_token != 0x0);
        token = CustomToken(_token);
        require(token.owner() == owner);
        require(token.auction_address() == address(this));

        // Get number of Tei (TKN * multiplier) to be auctioned from token auction balance
        tokens_auctioned = token.balanceOf(this);

        // Set number of tokens multiplier from token decimals
        multiplier = 10**uint(token.decimals());

        stage = Stages.AuctionSetUp;
        Setup();
    }

    /// @notice Set `_price_factor` and `_price_const` as the new price factor
    /// and price divisor constant.
    /// @dev Changes auction start price factor before auction is started.
    /// @param _price_factor Updated price factor.
    /// @param _price_const Updated price divisor constant.
    function changeSettings(uint _price_factor, uint _price_const) public isOwner {
        require(stage == Stages.AuctionDeployed || stage == Stages.AuctionSetUp);
        require(_price_factor > 0);
        require(_price_const > 0);

        price_factor = _price_factor;
        price_const = _price_const;
        SettingsChanged(price_factor, price_const);
    }

    /// @notice Start the auction.
    /// @dev Starts auction and sets start_time.
    function startAuction() public isOwner atStage(Stages.AuctionSetUp) {
        stage = Stages.AuctionStarted;
        start_time = now;
        start_block = block.number;
        AuctionStarted(start_time, start_block);
    }

    /// @notice Finalize the auction - sets the final price and changes the auction
    /// stage after no bids are allowed anymore.
    /// @dev Finalize auction and set the final token price.
    function finalizeAuction() public atStage(Stages.AuctionStarted)
    {
        // Missing funds should be 0 at this point
        uint missing_funds = missingFundsToEndAuction();
        require(missing_funds == 0);

        // Calculate the final price WEI / TKN = WEI / (Tei / multiplier)
        final_price = multiplier * received_ether / tokens_auctioned;

        end_time = now;
        stage = Stages.AuctionEnded;
        AuctionEnded(final_price);

        assert(final_price > 0);
    }

    /// --------------------------------- Auction Functions ------------------

    /// @notice Send `msg.value` WEI to the auction from the `msg.sender` account.
    /// @dev Allows to send a bid to the auction.
    function bid() public payable atStage(Stages.AuctionStarted) {
        bid(msg.sender);
    }

    /// @notice Send `msg.value` WEI to the auction from the `receiver` account.
    /// @dev Allows to send a bid to the auction.
    /// @param receiver Bidder account address.
    function bid(address receiver)
        public
        payable
        isValidPayload
        atStage(Stages.AuctionStarted)
    {
        require(receiver != 0x0);
        require(msg.value > 0);
        require(bids[receiver] + msg.value >= msg.value);

        uint pre_receiver_funds = bids[receiver];

        // Missing funds without the current bid value
        uint missing_funds = missingFundsToEndAuction();

        // We only allow bid values less than the missing funds to end the auction value.
        require(msg.value <= missing_funds);

        bids[receiver] += msg.value;
        received_ether += msg.value;

        // Send bid amount to wallet
        wallet.transfer(msg.value);

        BidSubmission(receiver, msg.value, missing_funds);

        assert(bids[receiver] == pre_receiver_funds + msg.value);
        assert(received_ether >= msg.value);
    }

    /// @notice Claim auction tokens for `msg.sender` after the auction has ended.
    /// @dev Claims tokens for bidder after auction. To be used if tokens can be claimed by bidders, individually.
    function claimTokens() public atStage(Stages.AuctionEnded) {
        claimTokens(msg.sender);
    }

    /// @notice Claim auction tokens for `receiver` after the auction has ended.
    /// @dev Claims tokens for bidder after auction.
    /// @param receiver Tokens will be assigned to this address if set.
    function claimTokens(address receiver)
        public
        isValidPayload
        atStage(Stages.AuctionEnded)
    {
        require(receiver != 0x0);
        require(bids[receiver] > 0);

        // Number of Tei = bidded_wei / wei_per_TKN * multiplier
        uint num = multiplier * bids[receiver] / final_price;

        // Update funds claimed with full bidded amount
        // rounding errors are included to not block the contract
        funds_claimed += bids[receiver];

        // Set receiver bid to 0 before assigning tokens
        bids[receiver] = 0;

        require(token.transfer(receiver, num));

        ClaimedTokens(receiver, num);

        // Test for a correct claimed tokens calculation
        /* TODO remove this after testing */
        uint auction_unclaimed_tokens = token.balanceOf(this);

        uint unclaimed_tokens = (received_ether - funds_claimed) * multiplier / final_price;
        unclaimed_tokens += rounding_error_tokens;

        if (auction_unclaimed_tokens != unclaimed_tokens) {
            rounding_error_tokens += 1;
            unclaimed_tokens += 1;
        }
        assert(auction_unclaimed_tokens == unclaimed_tokens);
        /* End of removable test */

        // After the last tokens are claimed, we send the auction balance to the owner
        // and change the auction stage
        if (funds_claimed == received_ether) {
            stage = Stages.TokensDistributed;
            TokensDistributed();
        }

        assert(token.balanceOf(receiver) >= num);
        assert(bids[receiver] == 0);
    }

    /*
     *  Private functions
     */

    /// @dev Calculates the token price (WEI / TKN) at the current timestamp
    /// during the auction; elapsed time = 0 before auction starts.
    /// @dev At AuctionDeployed the price is 1, because multiplier is 0
    /// @return Returns the token price - Wei per TKN.
    function calcTokenPrice() constant private returns (uint) {
        uint elapsed;
        if (stage == Stages.AuctionStarted) {
            elapsed = now - start_time;
        }
        return multiplier * price_factor / (elapsed + price_const) + 1;
    }

    /// --------------------------------- Price Functions ----------------------

    /// @notice Get the TKN price in WEI during the auction, at the moment of
    /// calling this method. Returns `0` if auction has ended.
    /// @dev Calculates current token price.
    /// @return Returns num Wei per TKN (multiplier * Tei).
    function price() public constant returns (uint) {
        if (stage == Stages.AuctionEnded ||
            stage == Stages.TokensDistributed) {
            return 0;
        }
        return calcTokenPrice();
    }

    /// @notice Get the missing funds needed to end the auction,
    /// calculated at the current TKN price.
    /// @dev The missing funds amount necessary to end the auction at the current price.
    /// @return Returns the missing funds amount.
    function missingFundsToEndAuction() constant public returns (uint) {
        uint funds_at_price = tokens_auctioned * price() / multiplier;
        if (funds_at_price < received_ether) {
            return 0;
        }
        return funds_at_price - received_ether;
    }
}


Fixed minor spelling error

Fixed minor spelling error

contract coin {}

contract issuer {
    address public issuerAddr;
    address public coinAddr;
    coin public pluton;

    struct Rebate {
        uint plutonRewardRate;
        uint plutonRewardRateReduceStep;
        uint plutonRewardRateReduce;
        uint requiredExchangeSpeed;
        uint currentExchangeSpeedRate;
        uint lastTimestamp;
        uint baseUnitForRebate;
        uint minPlutonRewardRate;
        uint currentExchangeSpeed;
    }
    Rebate public rebate;

    modifier ownerCheck { if (msg.sender == issuerAddr) _ }

    /*Initial */
    function issuer(address _issuer, coin _plutonAddr) {
        issuerAddr = _issuer;
        coinAddr = _plutonAddr;

        rebate.baseUnitForRebate = 1000; // accrual 0,1%
        rebate.plutonRewardRate = 30; // 3%
        rebate.minPlutonRewardRate = 10; // 1%

        rebate.plutonRewardRateReduce = 1; // reduce 0,1% from every plutonRewardRateReduceStep more in action more in action

        rebate.requiredExchangeSpeed = 10; // 10 BTC/sec
        rebate.plutonRewardRateReduceStep = 1; // for example: every 1 BTC/sec more in action reduce rate on plutonRewardRateReduce

        rebate.lastTimestamp = now;
        pluton = coin(_plutonAddr);
    }

    /* issuer functions */

    function getRebate(uint _btcAmount, string txID, address _btcSeller) ownerCheck returns(uint plutonReward) {
        rebate.currentExchangeSpeed =  _btcAmount / (now - rebate.lastTimestamp);
        uint reduce;
        reduce = (rebate.currentExchangeSpeed -  rebate.requiredExchangeSpeed) / rebate.plutonRewardRateReduceStep * rebate.plutonRewardRateReduce;
        if(reduce > rebate.currentExchangeSpeed) {rebate.plutonRewardRate = rebate.minPlutonRewardRate;}
        else if(rebate.currentExchangeSpeed > rebate.requiredExchangeSpeed) {
                rebate.plutonRewardRate = rebate.plutonRewardRate - reduce;}
                else {rebate.plutonRewardRate = rebate.plutonRewardRate + reduce;}

        plutonReward = _btcAmount * rebate.plutonRewardRate;
         //   pluton.emmision(plutonReward);
        //    pluton.transfer(plutonReward, _btcSeller);
    }

}

contract coin {}

contract issuer {
    address public issuerAddr;
    address public coinAddr;
    coin public pluton;

    struct Rebate {
        uint plutonRewardRate;
        uint plutonRewardRateReduceStep;
        uint plutonRewardRateReduce;
        uint reqieredExchangeSpeed;
        uint currentExchangeSpeedRate;
        uint lastTimestamp;
        uint baseUnitForRebate;
        uint minPlutonRewardRate;
        uint currentExchangeSpeed;
    }
    Rebate public rebate;

    modifier ownerCheck { if (msg.sender == issuerAddr) _ }

    /*Initial */
    function issuer(address _issuer, coin _plutonAddr) {
        issuerAddr = _issuer;
        coinAddr = _plutonAddr;

        rebate.baseUnitForRebate = 1000; // accrual 0,1%
        rebate.plutonRewardRate = 30; // 3%
        rebate.minPlutonRewardRate = 10; // 1%

        rebate.plutonRewardRateReduce = 1; // reduce 0,1% from every plutonRewardRateReduceStep more in action more in action

        rebate.reqieredExchangeSpeed = 10; // 10 BTC/sec
        rebate.plutonRewardRateReduceStep = 1; // for example: every 1 BTC/sec more in action reduce rate on plutonRewardRateReduce

        rebate.lastTimestamp = now;
        pluton = coin(_plutonAddr);
    }

    /* issuer functions */

    function getRebate(uint _btcAmount, string txID, address _btcSeller) ownerCheck returns(uint plutonReward) {
        rebate.currentExchangeSpeed =  _btcAmount / (now - rebate.lastTimestamp);
        uint reduce;
        reduce = (rebate.currentExchangeSpeed -  rebate.reqieredExchangeSpeed) / rebate.plutonRewardRateReduceStep * rebate.plutonRewardRateReduce;
        if(reduce > rebate.currentExchangeSpeed) {rebate.plutonRewardRate = rebate.minPlutonRewardRate;}
        else if(rebate.currentExchangeSpeed > rebate.reqieredExchangeSpeed) {
                rebate.plutonRewardRate = rebate.plutonRewardRate - reduce;}
                else {rebate.plutonRewardRate = rebate.plutonRewardRate + reduce;}

        plutonReward = _btcAmount * rebate.plutonRewardRate;
         //   pluton.emmision(plutonReward);
        //    pluton.transfer(plutonReward, _btcSeller);
    }

}


Delete GNTTokenTraderFactory.sol

Delete GNTTokenTraderFactory.sol

pragma solidity ^0.4.0;

//https://github.com/nexusdev/erc20/blob/master/contracts/erc20.sol

contract ERC20Constant {
    function balanceOf( address who ) constant returns (uint value);
}
contract ERC20Stateful {
    function transfer( address to, uint value) returns (bool ok);
}
contract ERC20Events {
    event Transfer(address indexed from, address indexed to, uint value);
}
contract ERC20 is ERC20Constant, ERC20Stateful, ERC20Events {}

contract owned {
    address public owner;

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

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

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

// contract can sell tokens for ETH
// prices are in amount of wei per batch of token units

contract TokenTrader is owned {

    address public asset;       // address of token
    uint256 public sellPrice;   // contract sells lots of tokens at this price
    uint256 public units;       // lot size (token-wei)

    bool public sellsTokens;    // is contract selling

    event ActivatedEvent(bool sells);
    event UpdateEvent();

    function TokenTrader (
        address _asset,
        uint256 _sellPrice,
        uint256 _units,
        bool    _sellsTokens
        )
    {
          asset         = _asset;
          sellPrice    = _sellPrice;
          units         = _units;
          sellsTokens   = _sellsTokens;

          ActivatedEvent(sellsTokens);
    }

    // modify trading behavior
    function activate (
        bool    _sellsTokens
        ) onlyOwner
    {
          sellsTokens   = _sellsTokens;

          ActivatedEvent(sellsTokens);
    }

    // allow owner to remove trade token
    function withdrawAsset(uint256 _value) onlyOwner returns (bool ok)
    {
        return ERC20(asset).transfer(owner,_value);
        UpdateEvent();
    }

    // allow owner to remove arbitrary tokens
    // included just in case contract receives wrong token
    function withdrawToken(address _token, uint256 _value) onlyOwner returns (bool ok)
    {
        return ERC20(_token).transfer(owner,_value);
        UpdateEvent();
    }

    // allow owner to remove ETH
    function withdraw(uint256 _value) onlyOwner returns (bool ok)
    {
        if(this.balance >= _value) {
            return owner.send(_value);
        }
        UpdateEvent();
    }

    //user buys token with ETH
    function buy() payable {
        if(sellsTokens || msg.sender == owner)
        {
            uint order   = msg.value / sellPrice;
            uint can_sell = ERC20(asset).balanceOf(address(this)) / units;

            if(order > can_sell)
            {
                uint256 change = msg.value - (can_sell * sellPrice);
                order = can_sell;
                if(!msg.sender.send(change)) throw;
            }

            if(order > 0) {
                if(!ERC20(asset).transfer(msg.sender,order * units)) throw;
            }
            UpdateEvent();
        }
        else if(!msg.sender.send(msg.value)) throw;  // return user funds if the contract is not selling
    }

    // sending ETH to contract sells GNT to user
    function () payable {
        buy();
    }
}

// This contract deploys TokenTrader contracts and logs the event
// trade pairs are identified with sha3(asset,units)

contract TokenTraderFactory {

    event TradeListing(bytes32 bookid, address owner, address addr);
    event NewBook(bytes32 bookid, address asset, uint256 units);

    mapping( address => bool ) _verify;
    mapping( bytes32 => bool ) pairExits;

    function verify(address tradeContract)  constant returns (
        bool valid,
        address asset,
        uint256 sellPrice,
        uint256 units,
        bool    sellsTokens
        ) {

            valid = _verify[tradeContract];

            if(valid) {
                TokenTrader t = TokenTrader(tradeContract);

                asset = t.asset();
                sellPrice = t.sellPrice();
                units = t.units();
                sellsTokens = t.sellsTokens();
            }

    }

    function createTradeContract(
        address _asset,
        uint256 _sellPrice,
        uint256 _units,
        bool    _sellsTokens
        ) returns (address)
    {
        if(_units == 0) throw;              // can't sell zero units

        address trader = new TokenTrader (
                     _asset,
                     _sellPrice,
                     _units,
                     _sellsTokens);

        var bookid = sha3(_asset,_units);

        _verify[trader] = true; // record that this factory created the trader

        TokenTrader(trader).transferOwnership(msg.sender); // set the owner to whoever called the function

        if(pairExits[bookid] == false) {
            pairExits[bookid] = true;
            NewBook(bookid, _asset, _units);
        }

        TradeListing(bookid,msg.sender,trader);
    }

    function () {
        throw;     // Prevents accidental sending of ether to the factory
    }
}