fix check and uint

fix check and uint

contract token {
    address public creator;
    string public symbol;
    string public name;
    uint public baseUnit;
    uint totalSupply;
    mapping (address => uint) public balanceOf;
    mapping (address => mapping(address => bool)) approveOf;
    mapping (address => mapping(address => bool)) approveOnceOf;
    mapping (address => mapping(address => uint)) approveOnceValueOf;

    modifier creatorCheck { if (msg.sender == creator) _ }

    /* Events */
    event Transfer(address indexed _from, address indexed _to, uint _value);
    event AddressApproval(address indexed _address, address indexed _proxy, bool _result);
    event AddressApprovalOnce(address indexed _address, address indexed _proxy, uint _value);

    /*Initial */
    function token(string _s, string _n, uint _unit) {
        creator = msg.sender;
        symbol = _s;
        name = _n;
        baseUnit = _unit;
    }

    /* Creator functions */
    function getTotalSupply()  creatorCheck returns (uint supply) {
        return totalSupply;
    }

    function emission(uint _amount) creatorCheck returns(bool result) {
        if (balanceOf[creator] + _amount < balanceOf[creator]) {return false;}
        balanceOf[creator] += _amount;
        totalSupply += _amount;
        return true;
    }

    function burn(uint _amount) creatorCheck returns(bool result) {
        if (balanceOf[creator] < _amount) {return false;}
        if (balanceOf[creator] + _amount < balanceOf[creator]) {return false;}
        balanceOf[creator] -= _amount;
        totalSupply -= _amount;
        return true;
    }

    /* Agent function */

    function myBalance() returns (uint256 balance) {
        balance = balanceOf[msg.sender];
        return balance;
    }

    function transfer(address _to, uint _value) returns (bool result) {
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint _value) returns (bool success) {
        if(approveOf[_from][msg.sender])
        {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        } else if(approveOnceOf[_from][msg.sender] && approveOnceValueOf[_from][msg.sender]=>_value) {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        }
    }

    function approve(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = true;
        AddressApproval(_address, msg.sender, true);
        return true;
    }

    function unapprove(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = false;
        return true;
    }

    function approveOnce(address _address, uint _maxValue) returns (bool result) {
        approveOnceOf[msg.sender][_address] = true;
        approveOnceValueOf[msg.sender][_address] = _maxValue;
        AddressApprovalOnce(_address, msg.sender, _maxValue);
        return true;
    }

    function unapproveOnce(address _address) returns (bool result) {
        approveOnceOf[msg.sender][_address] = false;
        approveOnceValueOf[msg.sender][_address] = 0;
        return true;
    }

    function isApprovedOnceFor(address _target, address _proxy) returns (uint maxValue) {
        maxValue = approveOnceValueOf[_target][_proxy];
        return maxValue;
    }

    function isApprovedFor(address _target, address _proxy) returns (bool result) {
        result = approveOnceOf[_target][_proxy];
        return result;
    }
}

contract token {
    address public creator;
    string public symbol;
    string public name;
    uint public baseUnit;
    uint totalSupply;
    mapping (address => uint) public balanceOf;
    mapping (address => mapping(address => bool)) approveOf;
    mapping (address => mapping(address => bool)) approveOnceOf;
    mapping (address => mapping(address => uint)) approveOnceValueOf;

    modifier creatorCheck { if (msg.sender == creator) _ }

    /* Events */
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event AddressApproval(address indexed _address, address indexed _proxy, bool _result);
    event AddressApprovalOnce(address indexed _address, address indexed _proxy, uint256 _value);

    /*Initial */
    function token(string _s, string _n, uint _unit) {
        creator = msg.sender;
        symbol = _s;
        name = _n;
        baseUnit = _unit;
    }

    /* Creator functions */
    function getTotalSupply()  creatorCheck returns (uint supply) {
        return totalSupply;
    }

    function emission(uint _amount) creatorCheck returns(bool result) {
        if (balanceOf[creator] + _amount < balanceOf[creator]) {return false;}
        balanceOf[creator] += _amount;
        totalSupply += _amount;
        return true;
    }

    function burn(uint _amount) creatorCheck returns(bool result) {
        if (balanceOf[creator] < _amount) {return false;}
        if (balanceOf[creator] + _amount < balanceOf[creator]) {return false;}
        balanceOf[creator] -= _amount;
        totalSupply -= _amount;
        return true;
    }

    /* Agent function */

    function myBalance() returns (uint256 balance) {
        balance = balanceOf[msg.sender];
        return balance;
    }

    function transfer(address _to, uint _value) returns (bool result) {
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint _value) returns (bool success) {
        if(approveOf[_from][msg.sender])
        {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        } else if(approveOnceOf[_from][msg.sender] && approveOnceValueOf[_from][msg.sender]<=_value) {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        }
    }

    function approve(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = true;
        AddressApproval(_address, msg.sender, true);
        return true;
    }

    function unapprove(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = false;
        return true;
    }

    function approveOnce(address _address, uint _maxValue) returns (bool result) {
        approveOnceOf[msg.sender][_address] = true;
        approveOnceValueOf[msg.sender][_address] = _maxValue;
        AddressApprovalOnce(_address, msg.sender, _maxValue);
        return true;
    }

    function unapproveOnce(address _address) returns (bool result) {
        approveOnceOf[msg.sender][_address] = false;
        approveOnceValueOf[msg.sender][_address] = 0;
        return true;
    }

    function isApprovedOnceFor(address _target, address _proxy) returns (uint maxValue) {
        maxValue = approveOnceValueOf[_target][_proxy];
        return maxValue;
    }

    function isApprovedFor(address _target, address _proxy) returns (bool result) {
        result = approveOnceOf[_target][_proxy];
        return result;
    }
}


Improve docs for ERC721URIStorage._burn (#3324)

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;

import "../ERC721.sol";

/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally checks to see if a
     * token-specific URI was set for the token, and if so, it deletes the token URI from
     * the storage mapping.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;

import "../ERC721.sol";

/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}


Refactored market contract

Refactored market contract

import 'token.sol';

/*
 * Token lot for market
 *   presents available deal based on token transfers
 */
contract Lot is Mortal {
    /* Operational tokens */
    Token public sale;
    Token public buy;

    /* Operational addreses */
    address public seller;
    address public buyer;

    /* Operation description */
    uint public value = 0; // Value of sale tokens
    uint public price = 0; // Price one sale token in buy tokens

    /* Lot is deal and closed */
    bool public closed = false;

    function Lot(Token _sale, Token _buy, uint _value, uint _price) {
        sale   = _sale;
        buy    = _buy;
        value  = _value;
        price  = _price;
        seller = msg.sender;
    }

    /* Lot deal with buyer is a sender */
    function deal() returns (bool) {
        return deal(msg.sender);
    }

    /* Lot deal method with buyer in argument */
    function deal(address _buyer) returns (bool) {
        /* So if lot is closed no deal available */
        if (closed) return false;

        /* Check it to deal this lot */
        if (sale.getBalance(seller) >= value
          && buy.getBalance(_buyer) >= value * price) {
            // Do transfer tokens
            sale.transferFrom(seller, _buyer, value);
            buy.transferFrom(_buyer, seller, value * price);
            // Store buyer and close lot
            buyer = _buyer;
            closed = true;
            return true;
        }
        return false;
    }
}

/*
 * Token based market contract
 */
contract Market is Mortal {
    /* Market configuration */
    struct Config {
        /* Market name */
        string name;
        /* Available market lots */
        Array.Data lots;
    }

    Config market;

    /* Common used array iterator */
    Array.Iterator it;

    /* Public getters */
    function getName() returns (string)
    { return market.name; }

    function getLotLength() returns (uint)
    { return Array.size(market.lots); }

    function getLot(uint _index) returns (Lot)
    { return Lot(Array.get(market.lots, _index)); }

    /* Market constructor */
    function Market(string _name) {
        market.name = _name;
    }

    /*
     * The lot on market manipulations
     */
    function placeLot(Lot _lot)
    { Array.append(market.lots, _lot); }

    function removeLot(Lot _lot) {
        if (_lot.seller() == msg.sender) {
            Array.setBegin(market.lots, it);
            Array.find(it, _lot);
            Array.remove(it);
        }
    }

    /*
     * Client public methods
     */
    function bestDeal(Token _buy, uint _value) returns (Lot) {
        Lot best = Lot(0);

        Array.setBegin(market.lots, it);
        while (!Array.end(it)) {
            var lot = Lot(Array.get(it));
            /* Drop closed lots from array */
            if (lot.closed()) {
                Array.remove(it);
                continue;
            }
            /* So the lot is candidate to best if token and value suit */
            if (lot.sale() == _buy && lot.value() >= _value)
                /* Best price - low price */
                if (best == Lot(0) || best.price() > lot.price())
                    best = lot;
            /* Step next */
            Array.next(it);
        }
        return best;
    }
}

contract market {
    address creator;
    token Token;
    etherToken EtherToken;

    struct Order {
        uint orderID;
        address owner;
        uint total;
        uint unitPrice;
        uint min;
        uint step;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    mapping (address => bool) public sellExistOf;
    mapping (address => uint) public sellDataOf;
    mapping (address => uint) public sellCountAsset;

    BuyAssetList[] public buyAssetList;
    mapping (address => bool) public buyExistOf;
    mapping (address => uint) public buyDataOf;
    mapping (address => uint) public buyCountAsset;

    function market(address _etherTokenAddr) {
        creator = msg.sender;
        EtherToken = etherToken(_etherTokenAddr);
    }

    function addSell(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint sellID) {
        uint assetID;
        if (sellExistOf[_assetAddr]) {
            assetID = sellDataOf[_assetAddr];
            SaleAssetList sellAssetOrders = sellAssetList[assetID];
        } else {
            assetID = sellAssetList.length++;
			sellDataOf[_assetAddr] = assetID;
            sellExistOf[_assetAddr] = true;
            sellAssetOrders = sellAssetList[assetID];
            sellAssetOrders.assetAddr = _assetAddr;
        }
        sellID = sellAssetOrders.sellOrderList.length++;

        Order order = sellAssetOrders.sellOrderList[sellID];
        order.orderID = sellID;
        order.owner = msg.sender;
        order.total = _total;
        order.unitPrice = _unitPrice;
        order.min = _min;
        order.step = _step;
        order.active = true;

        sellCountAsset[_assetAddr] = sellID;

        return sellID;
    }

    function addBuy(address _assetAddr, uint _total, uint _unitPrice, uint _min, uint _step) returns(uint buyID) {
        uint assetID;
        if (buyExistOf[_assetAddr]) {
            assetID = buyDataOf[_assetAddr];
            BuyAssetList buyAssetOrders = buyAssetList[assetID];
        } else {
            assetID = buyAssetList.length++;
			buyDataOf[_assetAddr] = assetID;
            buyExistOf[_assetAddr] = true;
            buyAssetOrders = buyAssetList[assetID];
            buyAssetOrders.assetAddr = _assetAddr;
        }
        buyID = buyAssetOrders.buyOrderList.length++;

        Order order = buyAssetOrders.buyOrderList[buyID];
        order.orderID = buyID;
        order.owner = msg.sender;
        order.total = _total;
        order.unitPrice = _unitPrice;
        order.min = _min;
        order.step = _step;
        order.active = true;

        buyCountAsset[_assetAddr] = buyID;

        return buyID;
    }

    function removeSell(address _assetAddr, uint _orderID) returns(bool) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            if (order.owner == msg.sender) {
                order.active = false;
                return true;
            }
        }
        return false;
    }

    function removeBuy(address _assetAddr, uint _orderID) returns(bool) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            if (order.owner == msg.sender) {
                order.active = false;
                return true;
            }
        }
        return false;
    }

    function downSell(address _assetAddr, uint _orderID, uint _total) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            order.total = order.total - _total;
            if (order.total == 0) {
                order.active = false;
            }
        }
    }

    function downBuy(address _assetAddr, uint _orderID, uint _total) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            order.total = order.total - _total;
            if (order.total == 0) {
                order.active = false;
            }
        }
    }

    function getSell(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
        }
    }

    function getBuy(address _assetAddr, uint _orderID) returns(address owner, uint total, uint unitPrice, uint min, uint step, bool active) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return (order.owner, order.total, order.unitPrice, order.min, order.step, order.active);
        }
    }

    function getSellOwner(address _assetAddr, uint _orderID) returns(address) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return order.owner;
        }
    }

    function getBuyOwner(address _assetAddr, uint _orderID) returns(address) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return order.owner;
        }
    }

    function getSellPrice(address _assetAddr, uint _orderID) returns(uint) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            return order.unitPrice;
        }
    }

    function getBuyPrice(address _assetAddr, uint _orderID) returns(uint) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            return order.unitPrice;
        }
    }

    function dealSell(address _assetAddr, uint _orderID) returns(bool) {
        if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
            Order order = sellAssetList[assetID].sellOrderList[_orderID];
            Token = token(_assetAddr);
            if (Token.balanceOf(order.owner) >= order.total && EtherToken.balanceOf(msg.sender) >= order.total * order.unitPrice) {
                order.active = false;
                Token.transferFrom(order.owner,msg.sender,order.total);
                EtherToken.transferFrom(msg.sender,order.owner,order.total * order.unitPrice);
                return true;
            }
        }
        return false;

    }

    function dealBuy(address _assetAddr, uint _orderID) returns(bool) {
        if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
            Order order = buyAssetList[assetID].buyOrderList[_orderID];
            Token = token(_assetAddr);
            if (EtherToken.balanceOf(order.owner) >= order.total * order.unitPrice && Token.balanceOf(msg.sender) >= order.total) {
                order.active = false;
                Token.transferFrom(msg.sender,order.owner,order.total);
                EtherToken.transferFrom(order.owner,msg.sender,order.total * order.unitPrice);
                return true;
            }
        }
        return false;
    }

}


It Compiles!

It Compiles!

// Library for operations on tasks
//TODO: USe "self" for method-like calls. Use "storage" keyword for library calls
contract Validator{ //Abstract contract defining validator ABI
    function validate(uint taskID, bytes data) returns (bool val);
}

library Tasks {
    struct Task { //TODO: Define tasks
        address user;
        uint taskID;
        byte[] ipfsData; //note: ipfs uses arbitrary-length addresses
        uint startTime;
        uint duration;
        address validator;
        uint penalty; //penalty for not completing, denominated in whatever token the Goal uses
        uint reward;
        uint frequency; // 0 if single task, repeat period if > 0
        uint nextTask;  //linked list structure
        uint prevTask;
    }

    struct taskList{  //TODO: fix all the things
        uint first;
        uint last;
        Tasks.Task[] tasks; //Sorted in order of due date
    }

    function validate(Task storage self, bytes validationData) returns (bool){
        if(block.timestamp > self.startTime && block.timestamp < self.startTime + self.duration){
            return  Validator(self.validator).validate(self.taskID, validationData);
        }
        return false;
    }

    function complete(taskList storage self, uint ID, bytes validationData) returns (uint reward){ //validate, re-add, and return reward amount
        uint penalty = clean(self);
        uint index = findID(self,ID);
        if(validate(self.tasks[index], validationData)){
            reward += self.tasks[index].reward;
            remove(self, index);
        }
    }

    function remove(taskList storage self, uint index){ //Remove task while maintaining sort order
        self.tasks[self.tasks[index].nextTask].prevTask = self.tasks[index].prevTask;
        self.tasks[self.tasks[index].prevTask].nextTask = self.tasks[index].nextTask;
        delete self.tasks[index];
    }                                                                                // TODO: Create linked list for tasks

    /*function add(Task[] tasks, Task newTask){                                         // OLD array based list structure
        tasks.length++;
        for(uint i=tasks.length-1, i > 0, i--;){
            if(tasks[i-1].endTime <= newTask.endTime){
                tasks[i] = newTask;
                break;
            }
            else{
                tasks[i] = tasks[i-1];
            }

        }
    }*/

    function add(taskList storage self, Task storage newTask){
        uint index;
        for(uint j=0; j < self.tasks.length; j++){ //Insert task into array
            if(self.tasks[j].taskID == 0){
                self.tasks[j] = newTask;
                index = j;
            }
            else if(i==self.tasks.length-1){
                self.tasks.push(newTask);
            }
        }
        uint i = self.last;
        while(self.tasks[i].startTime+self.tasks[i].duration > newTask.startTime + newTask.duration){
            i=self.tasks[i].prevTask;
        }
        self.tasks[self.tasks[i].nextTask].prevTask = index;
        self.tasks[i].nextTask = index;

    }

// TODO: Implement clean using new linked list
   /*  function clean(Task[] tasks) returns (uint penalty){
        uint penalty;
        for(uint i=0, i<tasks.length, i++){
            if(tasks[i].startTime < block.timestamp){
                penalty += tasks[i].penalty;
                remove(tasks,i);
            }
            else break;
        }
    }
    */

    function clean(taskList storage self) returns (uint){
        uint penalty;
        uint i = self.first;
        while (self.tasks[i].startTime+self.tasks[i].duration< block.timestamp){
            penalty+=self.tasks[i].penalty;
            remove(self, i);
        }
        return penalty;
    }

    function findID(taskList storage self, uint ID) returns (uint){
        for(uint i; i < self.tasks.length; i++){
            if(self.tasks[i].taskID == ID) return i;
        }
        throw;
    }

}

// Library for operations on tasks

contract Validator{ //Abstract contract defining validator ABI
    function validate(uint taskID, bytes data) returns (bool val);
}

library Tasks {
    struct Task { //TODO: Define tasks
        address user;
        uint taskID;
        byte[] ipfsData; //note: ipfs uses arbitrary-length addresses
        uint statTime;
        uint duration;
        address validator;
        uint penalty; //penalty for not completing, denominated in whatever token the Goal uses
        uint reward;
        uint frequency; // 0 if single task, repeat period if > 0
        uint nextTask;  //linked list structure
        uint prevTask;
    }

    struct taskList{  //TODO: fix all the things
        uint first;
        uint last;
        Tasks.Task[] tasks; //Sorted in order of due date
    }

    function validate(Task task, bytes validationData) returns (bool){
        if(block.timestamp > task.startTime && (block.timestamp < task.endTime){
            return  Validator(task.validator).validate(task.taskID, validationData);
        }
        return false;
    }

    function complete(Task[] tasks, uint index, bytes validationData) returns (uint reward){ //validate, re-add, and return reward amount
        uint reward;
        uint penalty = clean(tasks);
        if(validate(task, validationData)){
            reward += tasks[index].reward;
            remove(tasks, index);
        }
    }

    function remove(taskList list, uint index){ //Remove task while maintaining sort order
        Task task = list.tasks[index];
        list.tasks[task.nextTask].prevTask = list.task.prevTask;
        list.tasks[list.task.prevTask].nextTask = list.task.nextTask;
        delete list.\tasks[index];
    }                                                                                // TODO: Create linked list for tasks

    /*function add(Task[] tasks, Task newTask){                                         // OLD array based list structure
        tasks.length++;
        for(uint i=tasks.length-1, i > 0, i--;){
            if(tasks[i-1].endTime <= newTask.endTime){
                tasks[i] = newTask;
                break;
            }
            else{
                tasks[i] = tasks[i-1];
            }

        }
    }*/

    function add(Task[] tasks, Task newTask uint last){
        uint index;
        for(uint j=0, j < tasks.length, j++){ //Insert task into array
            if(tasks[j].taskID == 0){
                tasks[j] = newTask;
                index = j;
            }
            else if(i==tasks.length-1){
                tasks.push(newTask);
            }
        }
        uint i = last;
        while(tasks[i].startTime+tasks[i].duration > newTask.startTime + newTask.duration){
            i=tasks[i].prevTask;
        }
        tasks[tasks[i].nextTask].prevTask = index;
        tasks[i].nextTask = index;

    }

// TODO: Implement clean using new linked list
   /*  function clean(Task[] tasks) returns (uint penalty){
        uint penalty;
        for(uint i=0, i<tasks.length, i++){
            if(tasks[i].startTime < block.timestamp){
                penalty += tasks[i].penalty;
                remove(tasks,i);
            }
            else break;
        }
    }
    */

    function clean(Task[] tasks, uint first){
        uint penalty;
        uint i = first;
        while (tasks[i].startTime+tasks[i].time< block.timestamp){
            penalty+=tasks[i].penalty;
            remove(tasks, i);
        }
        return penalty
    }

}


Declare all Ln2 Scaling Factors as global constants

These constants are dependent on the MIN_PRECISION and MAX_PRECISION constants.
A python script that generates them is referenced from the code, and will be added separately.

pragma solidity ^0.4.11;
import './SafeMath.sol';
import './interfaces/IBancorFormula.sol';

contract BancorFormula is IBancorFormula, SafeMath {

    string public version = '0.2';

    uint256[128] maxExpArray;
    uint256 constant UINT256_1 = 1;
    uint256 constant UINT256_2 = 2;
    uint256 constant UINT256_3 = 3;
    uint8 constant MIN_PRECISION = 32;
    uint8 constant MAX_PRECISION = 127;

    /**
        These values can be auto-generated by the script 'PrintLn2ScalingFactors.py'.
    */
    uint256 constant CEILING_LN2_MANTISSA = 0xb17217f8;
    uint256 constant FLOOR_LN2_MANTISSA   = 0x2c5c85fdf473de6af278ece600fcbda;
    uint8   constant FLOOR_LN2_EXPONENT   = 122;

    /**
        This function can be auto-generated by the script 'PrintFunctionBancorFormula.py'.
    */
    function BancorFormula() {
    //  maxExpArray[  0] = 0xc1;
    //  maxExpArray[  1] = 0x17a;
    //  maxExpArray[  2] = 0x2e5;
    //  maxExpArray[  3] = 0x5ab;
    //  maxExpArray[  4] = 0xb1b;
    //  maxExpArray[  5] = 0x15bf;
    //  maxExpArray[  6] = 0x2a0c;
    //  maxExpArray[  7] = 0x50a2;
    //  maxExpArray[  8] = 0x9aa2;
    //  maxExpArray[  9] = 0x1288c;
    //  maxExpArray[ 10] = 0x238b2;
    //  maxExpArray[ 11] = 0x4429a;
    //  maxExpArray[ 12] = 0x82b78;
    //  maxExpArray[ 13] = 0xfaadc;
    //  maxExpArray[ 14] = 0x1e0bb8;
    //  maxExpArray[ 15] = 0x399e96;
    //  maxExpArray[ 16] = 0x6e7f88;
    //  maxExpArray[ 17] = 0xd3e7a3;
    //  maxExpArray[ 18] = 0x1965fea;
    //  maxExpArray[ 19] = 0x30b5057;
    //  maxExpArray[ 20] = 0x5d681f3;
    //  maxExpArray[ 21] = 0xb320d03;
    //  maxExpArray[ 22] = 0x15784a40;
    //  maxExpArray[ 23] = 0x292c5bdd;
    //  maxExpArray[ 24] = 0x4ef57b9b;
    //  maxExpArray[ 25] = 0x976bd995;
    //  maxExpArray[ 26] = 0x122624e32;
    //  maxExpArray[ 27] = 0x22ce03cd5;
    //  maxExpArray[ 28] = 0x42beef808;
    //  maxExpArray[ 29] = 0x7ffffffff;
    //  maxExpArray[ 30] = 0xf577eded5;
    //  maxExpArray[ 31] = 0x1d6bd8b2eb;
        maxExpArray[ 32] = 0x386bfdba29;
        maxExpArray[ 33] = 0x6c3390ecc8;
        maxExpArray[ 34] = 0xcf8014760f;
        maxExpArray[ 35] = 0x18ded91f0e7;
        maxExpArray[ 36] = 0x2fb1d8fe082;
        maxExpArray[ 37] = 0x5b771955b36;
        maxExpArray[ 38] = 0xaf67a93bb50;
        maxExpArray[ 39] = 0x15060c256cb2;
        maxExpArray[ 40] = 0x285145f31ae5;
        maxExpArray[ 41] = 0x4d5156639708;
        maxExpArray[ 42] = 0x944620b0e70e;
        maxExpArray[ 43] = 0x11c592761c666;
        maxExpArray[ 44] = 0x2214d10d014ea;
        maxExpArray[ 45] = 0x415bc6d6fb7dd;
        maxExpArray[ 46] = 0x7d56e76777fc5;
        maxExpArray[ 47] = 0xf05dc6b27edad;
        maxExpArray[ 48] = 0x1ccf4b44bb4820;
        maxExpArray[ 49] = 0x373fc456c53bb7;
        maxExpArray[ 50] = 0x69f3d1c921891c;
        maxExpArray[ 51] = 0xcb2ff529eb71e4;
        maxExpArray[ 52] = 0x185a82b87b72e95;
        maxExpArray[ 53] = 0x2eb40f9f620fda6;
        maxExpArray[ 54] = 0x5990681d961a1ea;
        maxExpArray[ 55] = 0xabc25204e02828d;
        maxExpArray[ 56] = 0x14962dee9dc97640;
        maxExpArray[ 57] = 0x277abdcdab07d5a7;
        maxExpArray[ 58] = 0x4bb5ecca963d54ab;
        maxExpArray[ 59] = 0x9131271922eaa606;
        maxExpArray[ 60] = 0x116701e6ab0cd188d;
        maxExpArray[ 61] = 0x215f77c045fbe8856;
        maxExpArray[ 62] = 0x3ffffffffffffffff;
        maxExpArray[ 63] = 0x7abbf6f6abb9d087f;
        maxExpArray[ 64] = 0xeb5ec597592befbf4;
        maxExpArray[ 65] = 0x1c35fedd14b861eb04;
        maxExpArray[ 66] = 0x3619c87664579bc94a;
        maxExpArray[ 67] = 0x67c00a3b07ffc01fd6;
        maxExpArray[ 68] = 0xc6f6c8f8739773a7a4;
        maxExpArray[ 69] = 0x17d8ec7f04136f4e561;
        maxExpArray[ 70] = 0x2dbb8caad9b7097b91a;
        maxExpArray[ 71] = 0x57b3d49dda84556d6f6;
        maxExpArray[ 72] = 0xa830612b6591d9d9e61;
        maxExpArray[ 73] = 0x1428a2f98d728ae223dd;
        maxExpArray[ 74] = 0x26a8ab31cb8464ed99e1;
        maxExpArray[ 75] = 0x4a23105873875bd52dfd;
        maxExpArray[ 76] = 0x8e2c93b0e33355320ead;
        maxExpArray[ 77] = 0x110a688680a7530515f3e;
        maxExpArray[ 78] = 0x20ade36b7dbeeb8d79659;
        maxExpArray[ 79] = 0x3eab73b3bbfe282243ce1;
        maxExpArray[ 80] = 0x782ee3593f6d69831c453;
        maxExpArray[ 81] = 0xe67a5a25da41063de1495;
        maxExpArray[ 82] = 0x1b9fe22b629ddbbcdf8754;
        maxExpArray[ 83] = 0x34f9e8e490c48e67e6ab8b;
        maxExpArray[ 84] = 0x6597fa94f5b8f20ac16666;
        maxExpArray[ 85] = 0xc2d415c3db974ab32a5184;
        maxExpArray[ 86] = 0x175a07cfb107ed35ab61430;
        maxExpArray[ 87] = 0x2cc8340ecb0d0f520a6af58;
        maxExpArray[ 88] = 0x55e129027014146b9e37405;
        maxExpArray[ 89] = 0xa4b16f74ee4bb2040a1ec6c;
        maxExpArray[ 90] = 0x13bd5ee6d583ead3bd636b5c;
        maxExpArray[ 91] = 0x25daf6654b1eaa55fd64df5e;
        maxExpArray[ 92] = 0x4898938c9175530325b9d116;
        maxExpArray[ 93] = 0x8b380f3558668c46c91c49a2;
        maxExpArray[ 94] = 0x10afbbe022fdf442b2a522507;
        maxExpArray[ 95] = 0x1ffffffffffffffffffffffff;
        maxExpArray[ 96] = 0x3d5dfb7b55dce843f89a7dbcb;
        maxExpArray[ 97] = 0x75af62cbac95f7dfa3295ec26;
        maxExpArray[ 98] = 0xe1aff6e8a5c30f58221fbf899;
        maxExpArray[ 99] = 0x1b0ce43b322bcde4a56e8ada5a;
        maxExpArray[100] = 0x33e0051d83ffe00feb432b473b;
        maxExpArray[101] = 0x637b647c39cbb9d3d26c56e949;
        maxExpArray[102] = 0xbec763f8209b7a72b0afea0d31;
        maxExpArray[103] = 0x16ddc6556cdb84bdc8d12d22e6f;
        maxExpArray[104] = 0x2bd9ea4eed422ab6b7b072b029e;
        maxExpArray[105] = 0x54183095b2c8ececf30dd533d03;
        maxExpArray[106] = 0xa14517cc6b9457111eed5b8adf1;
        maxExpArray[107] = 0x13545598e5c23276ccf0ede68034;
        maxExpArray[108] = 0x2511882c39c3adea96fec2102329;
        maxExpArray[109] = 0x471649d87199aa990756806903c5;
        maxExpArray[110] = 0x88534434053a9828af9f37367ee6;
        maxExpArray[111] = 0x1056f1b5bedf75c6bcb2ce8aed428;
        maxExpArray[112] = 0x1f55b9d9ddff141121e70ebe0104e;
        maxExpArray[113] = 0x3c1771ac9fb6b4c18e229803dae82;
        maxExpArray[114] = 0x733d2d12ed20831ef0a4aead8c66d;
        maxExpArray[115] = 0xdcff115b14eedde6fc3aa5353f2e4;
        maxExpArray[116] = 0x1a7cf47248624733f355c5c1f0d1f1;
        maxExpArray[117] = 0x32cbfd4a7adc790560b3335687b89b;
        maxExpArray[118] = 0x616a0ae1edcba5599528c20605b3f6;
        maxExpArray[119] = 0xbad03e7d883f69ad5b0a186184e06b;
        maxExpArray[120] = 0x16641a07658687a905357ac0ebe198b;
        maxExpArray[121] = 0x2af09481380a0a35cf1ba02f36c6a56;
        maxExpArray[122] = 0x5258b7ba7725d902050f6360afddf96;
        maxExpArray[123] = 0x9deaf736ac1f569deb1b5ae3f36c130;
        maxExpArray[124] = 0x12ed7b32a58f552afeb26faf21deca06;
        maxExpArray[125] = 0x244c49c648baa98192dce88b42f53caf;
        maxExpArray[126] = 0x459c079aac334623648e24d17c74b3dc;
        maxExpArray[127] = 0x6ae67b5f2f528d5f3189036ee0f27453;
    }

    /**
        @dev given a token supply, reserve, CRR and a deposit amount (in the reserve token), calculates the return for a given change (in the main token)

        Formula:
        Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / 100) - 1)

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _depositAmount      deposit amount, in reserve token

        @return purchase return amount
    */
    function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint8 _reserveRatio, uint256 _depositAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100);

        // special case for 0 deposit amount
        if (_depositAmount == 0)
            return 0;

        uint256 baseN = safeAdd(_depositAmount, _reserveBalance);
        uint256 temp;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp = safeMul(_supply, baseN) / _reserveBalance;
            return safeSub(temp, _supply);
        }

        uint8 precision = calculateBestPrecision(baseN, _reserveBalance, _reserveRatio, 100);
        uint256 resN = power(baseN, _reserveBalance, _reserveRatio, 100, precision);
        temp = safeMul(_supply, resN) >> precision;
        return safeSub(temp, _supply);
     }

    /**
        @dev given a token supply, reserve, CRR and a sell amount (in the main token), calculates the return for a given change (in the reserve token)

        Formula:
        Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_reserveRatio / 100)))

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _sellAmount         sell amount, in the token itself

        @return sale return amount
    */
    function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint8 _reserveRatio, uint256 _sellAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100 && _sellAmount <= _supply);

        // special case for 0 sell amount
        if (_sellAmount == 0)
            return 0;

        uint256 baseD = safeSub(_supply, _sellAmount);
        uint256 temp1;
        uint256 temp2;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp1 = safeMul(_reserveBalance, _supply);
            temp2 = safeMul(_reserveBalance, baseD);
            return safeSub(temp1, temp2) / _supply;
        }

        // special case for selling the entire supply
        if (_sellAmount == _supply)
            return _reserveBalance;

        uint8 precision = calculateBestPrecision(_supply, baseD, 100, _reserveRatio);
        uint256 resN = power(_supply, baseD, 100, _reserveRatio, precision);
        temp1 = safeMul(_reserveBalance, resN);
        temp2 = safeMul(_reserveBalance, UINT256_1 << precision);
        return safeSub(temp1, temp2) / resN;
    }

    /**
        Predicts the highest precision which can be used in order to compute "base ^ exp" without exceeding 256 bits in any of the intermediate computations.
        Instead of calculating "base ^ exp", we calculate "e ^ (ln(base) * exp)".
        The value of "ln(base)" is represented with an integer slightly smaller than "ln(base) * 2 ^ precision".
        The larger "precision" is, the more accurately this value represents the real value.
        However, the larger "precision" is, the more bits are required in order to store this value.
        And the exponentiation function, which takes "x" and calculates "e ^ x", is limited to a maximum exponent (maximum value of "x").
        This maximum exponent depends on the precision used ("maxExpArray" maps each precision between 0 and 127 to its maximum exponent).
        Hence before calling the exponentiation function, we need to determine the highest precision which can be used.
        We do this by estimating an upper-bound for "ln(base) * exp", and then choosing the highest precision which this value is permitted for.
        Of course, we should later assert that the actual value representing "ln(base) * exp" is indeed not larger than the maximum exponent of the chosen precision.
        Note that the outcome of this function only affects the accuracy of the computation of "base ^ exp".
        Therefore, we do not need to assert that no intermediate result exceeds 256 bits (nor in this function, neither in any of the functions down the calling tree).
    */
    function calculateBestPrecision(uint256 _baseN, uint256 _baseD, uint256 _expN, uint256 _expD) constant returns (uint8) {
        uint256 maxVal = lnUpperBound(_baseN, _baseD) * _expN;
        uint8 lo = MIN_PRECISION;
        uint8 hi = MAX_PRECISION;
        while (lo + 1 < hi) {
            uint8 mid = (lo + hi) / 2;
            if ((maxVal << (mid - MIN_PRECISION)) / _expD <= maxExpArray[mid])
                lo = mid;
            else
                hi = mid;
        }
        if ((maxVal << (hi - MIN_PRECISION)) / _expD <= maxExpArray[hi])
            return hi;
        else
            return lo;
    }

    /**
        Calculates an integer approximation of "(_baseN / _baseD) ^ (_expN / _expD) * 2 ^ _precision".
        This method is overflow-safe.
    */
    function power(uint256 _baseN, uint256 _baseD, uint256 _expN, uint256 _expD, uint8 _precision) constant returns (uint256) {
        uint256 logbase = ln(_baseN, _baseD, _precision);
        return fixedExp(safeMul(logbase, _expN) / _expD, _precision);
    }

    /**
        input range:
            - numerator: [1, uint256_max / 2 ^ precision]
            - denominator: [1, numerator]
            If numerator / denominator < 1 then ln(numerator / denominator) < 0
        output range:
            [0, ln(uint256_max) * 2 ^ precision]

        This method asserts outside of bounds
    */
    function ln(uint256 _numerator, uint256 _denominator, uint8 _precision) public constant returns (uint256) {
        assert(0 < _denominator && _denominator <= _numerator && _numerator < (UINT256_1 << (256 - _precision)));
        return fixedLoge( (_numerator << _precision) / _denominator, _precision);
    }

    /**
        Takes a rational number "numerator / denominator" as input.
        Returns an integer upper-bound of the natural logarithm of the input scaled by "2 ^ MIN_PRECISION".
        We do this by calculating "Ceiling(log2(numerator / denominator)) * Ceiling(ln(2) * 2 ^ MIN_PRECISION)".
        For small values of "numerator / denominator", this sometimes yields a bad upper-bound approximation.
        We therefore cover these cases (and a few more) manually.
        Complexity is O(log(input bit-length)).
    */
    function lnUpperBound(uint256 _numerator, uint256 _denominator) constant returns (uint256) {
        assert(_numerator > _denominator);

        uint256 scaledNumerator = _numerator << MIN_PRECISION;
        if (scaledNumerator <= _denominator *  0x2b7e15162) // _numerator / _denominator < e^1 (floorLog2 will return 0 if _numerator / _denominator < 2)
            return UINT256_1 << MIN_PRECISION;
        if (scaledNumerator <= _denominator *  0x763992e35) // _numerator / _denominator < e^2 (floorLog2 will return 1 if _numerator / _denominator < 4)
            return UINT256_2 << MIN_PRECISION;
        if (scaledNumerator <= _denominator * 0x1415e5bf6f) // _numerator / _denominator < e^3 (floorLog2 will return 2 if _numerator / _denominator < 8)
            return UINT256_3 << MIN_PRECISION;

        return ceilLog2(_numerator, _denominator) * CEILING_LN2_MANTISSA;
    }

    /**
        Returns floor(ln(x / 2 ^ precision) * 2 ^ precision)
    */
    function fixedLoge(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 log2 = fixedLog2(_x, _precision);
        return (log2 * FLOOR_LN2_MANTISSA) >> FLOOR_LN2_EXPONENT;
    }

    /**
        Returns floor(log2(x / 2 ^ precision) * 2 ^ precision)

        Ranges:
            precision between MIN_PRECISION and MAX_PRECISION
            x         between 2 ^ precision and (2 ^ (256 - precision) - 1) * (2 ^ precision)
            output    between 0             and floor(log2(2 ^ (256 - precision) - 1) * 2 ^ precision)
    */
    function fixedLog2(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 hi = 0;
        uint256 fixedOne = UINT256_1 << _precision;
        uint256 fixedTwo = UINT256_2 << _precision;

        while (_x >= fixedTwo) {
            _x >>= 1;
            hi += fixedOne;
        }

        for (uint8 i = 0; i < _precision; ++i) {
            _x = (_x * _x) / fixedOne;
            if (_x >= fixedTwo) {
                _x >>= 1;
                hi += UINT256_1 << (_precision - 1 - i);
            }
        }

        return hi;
    }

    /**
        Takes a rational number "numerator / denominator" as input.
        Returns the smallest integer larger than or equal to the binary logarithm of the input.
        Complexity is O(log(input bit-length)).
    */
    function ceilLog2(uint256 _numerator, uint256 _denominator) constant returns (uint256) {
        return floorLog2((_numerator - 1) / _denominator) + 1;
    }

    /**
        Takes a natural number "n" as input.
        Returns the largest integer smaller than or equal to the binary logarithm of the input.
        Complexity is O(log(input bit-length)).
    */
    function floorLog2(uint256 _n) constant returns (uint256) {
        uint8 t = 0;
        for (uint8 s = 128; s > 0; s >>= 1) {
            if (_n >= (UINT256_1 << s)) {
                _n >>= s;
                t |= s;
            }
        }

        return t;
    }

    /**
        fixedExp is a 'protected' version of fixedExpUnsafe, which asserts instead of overflows.
        The maximum value which can be passed to fixedExpUnsafe depends on the precision used.
        The global maxExpArray maps each precision between 0 and 127 to the maximum value permitted.
    */
    function fixedExp(uint256 _x, uint8 _precision) constant returns (uint256) {
        assert(_x <= maxExpArray[_precision]);
        return fixedExpUnsafe(_x, _precision);
    }

    /**
        This function can be auto-generated by the script 'PrintFunctionFixedExpUnsafe.py'.
        It approximates "e ^ x" via maclauren summation: "(x^0)/0! + (x^1)/1! + ... + (x^n)/n!".
        It returns "e ^ (x >> precision) << precision", that is, the result is upshifted for accuracy.
        The maximum permitted value for _x depends on the value of _precision (see maxExpArray).
    */
    function fixedExpUnsafe(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 xi = _x;
        uint256 res = uint256(0xde1bc4d19efcac82445da75b00000000) << _precision;

        res += xi * 0xde1bc4d19efcac82445da75b00000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x6f0de268cf7e5641222ed3ad80000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x2504a0cd9a7f7215b60f9be480000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x9412833669fdc856d83e6f920000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x1d9d4d714865f4de2b3fafea0000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x4ef8ce836bba8cfb1dff2a70000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xb481d807d1aa66d04490610000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x16903b00fa354cda08920c2000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x281cdaac677b334ab9e732000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x402e2aad725eb8778fd85000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x5d5a6c9f31fe2396a2af000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x7c7890d442a82f73839400000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x9931ed54034526b58e400000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xaf147cf24ce150cf7e00000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xbac08546b867cdaa200000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xbac08546b867cdaa20000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xafc441338061b2820000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x9c3cabbc0056d790000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x839168328705c30000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x694120286c049c000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x50319e98b3d2c000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x3a52a1e36b82000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x289286e0fce000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x1b0c59eb53400;
        xi = (xi * _x) >> _precision;
        res += xi * 0x114f95b55400;
        xi = (xi * _x) >> _precision;
        res += xi * 0xaa7210d200;
        xi = (xi * _x) >> _precision;
        res += xi * 0x650139600;
        xi = (xi * _x) >> _precision;
        res += xi * 0x39b78e80;
        xi = (xi * _x) >> _precision;
        res += xi * 0x1fd8080;
        xi = (xi * _x) >> _precision;
        res += xi * 0x10fbc0;
        xi = (xi * _x) >> _precision;
        res += xi * 0x8c40;
        xi = (xi * _x) >> _precision;
        res += xi * 0x462;
        xi = (xi * _x) >> _precision;
        res += xi * 0x22;

        return res / 0xde1bc4d19efcac82445da75b00000000;
    }
}

pragma solidity ^0.4.11;
import './SafeMath.sol';
import './interfaces/IBancorFormula.sol';

contract BancorFormula is IBancorFormula, SafeMath {

    uint256[128] maxExpArray;
    uint256 constant UINT256_1 = 1;
    uint256 constant UINT256_2 = 2;
    uint256 constant UINT256_3 = 3;
    uint8 constant MIN_PRECISION = 32;
    uint8 constant MAX_PRECISION = 127;
    uint256 constant CEILING_LN2 = 0xb17217f8; // Ceiling(ln(2) * 2 ^ MIN_PRECISION)
    string public version = '0.2';

    /**
        This function can be auto-generated by the script 'PrintFunctionBancorFormula.py'.
    */
    function BancorFormula() {
    //  maxExpArray[  0] = 0xc1;
    //  maxExpArray[  1] = 0x17a;
    //  maxExpArray[  2] = 0x2e5;
    //  maxExpArray[  3] = 0x5ab;
    //  maxExpArray[  4] = 0xb1b;
    //  maxExpArray[  5] = 0x15bf;
    //  maxExpArray[  6] = 0x2a0c;
    //  maxExpArray[  7] = 0x50a2;
    //  maxExpArray[  8] = 0x9aa2;
    //  maxExpArray[  9] = 0x1288c;
    //  maxExpArray[ 10] = 0x238b2;
    //  maxExpArray[ 11] = 0x4429a;
    //  maxExpArray[ 12] = 0x82b78;
    //  maxExpArray[ 13] = 0xfaadc;
    //  maxExpArray[ 14] = 0x1e0bb8;
    //  maxExpArray[ 15] = 0x399e96;
    //  maxExpArray[ 16] = 0x6e7f88;
    //  maxExpArray[ 17] = 0xd3e7a3;
    //  maxExpArray[ 18] = 0x1965fea;
    //  maxExpArray[ 19] = 0x30b5057;
    //  maxExpArray[ 20] = 0x5d681f3;
    //  maxExpArray[ 21] = 0xb320d03;
    //  maxExpArray[ 22] = 0x15784a40;
    //  maxExpArray[ 23] = 0x292c5bdd;
    //  maxExpArray[ 24] = 0x4ef57b9b;
    //  maxExpArray[ 25] = 0x976bd995;
    //  maxExpArray[ 26] = 0x122624e32;
    //  maxExpArray[ 27] = 0x22ce03cd5;
    //  maxExpArray[ 28] = 0x42beef808;
    //  maxExpArray[ 29] = 0x7ffffffff;
    //  maxExpArray[ 30] = 0xf577eded5;
    //  maxExpArray[ 31] = 0x1d6bd8b2eb;
        maxExpArray[ 32] = 0x386bfdba29;
        maxExpArray[ 33] = 0x6c3390ecc8;
        maxExpArray[ 34] = 0xcf8014760f;
        maxExpArray[ 35] = 0x18ded91f0e7;
        maxExpArray[ 36] = 0x2fb1d8fe082;
        maxExpArray[ 37] = 0x5b771955b36;
        maxExpArray[ 38] = 0xaf67a93bb50;
        maxExpArray[ 39] = 0x15060c256cb2;
        maxExpArray[ 40] = 0x285145f31ae5;
        maxExpArray[ 41] = 0x4d5156639708;
        maxExpArray[ 42] = 0x944620b0e70e;
        maxExpArray[ 43] = 0x11c592761c666;
        maxExpArray[ 44] = 0x2214d10d014ea;
        maxExpArray[ 45] = 0x415bc6d6fb7dd;
        maxExpArray[ 46] = 0x7d56e76777fc5;
        maxExpArray[ 47] = 0xf05dc6b27edad;
        maxExpArray[ 48] = 0x1ccf4b44bb4820;
        maxExpArray[ 49] = 0x373fc456c53bb7;
        maxExpArray[ 50] = 0x69f3d1c921891c;
        maxExpArray[ 51] = 0xcb2ff529eb71e4;
        maxExpArray[ 52] = 0x185a82b87b72e95;
        maxExpArray[ 53] = 0x2eb40f9f620fda6;
        maxExpArray[ 54] = 0x5990681d961a1ea;
        maxExpArray[ 55] = 0xabc25204e02828d;
        maxExpArray[ 56] = 0x14962dee9dc97640;
        maxExpArray[ 57] = 0x277abdcdab07d5a7;
        maxExpArray[ 58] = 0x4bb5ecca963d54ab;
        maxExpArray[ 59] = 0x9131271922eaa606;
        maxExpArray[ 60] = 0x116701e6ab0cd188d;
        maxExpArray[ 61] = 0x215f77c045fbe8856;
        maxExpArray[ 62] = 0x3ffffffffffffffff;
        maxExpArray[ 63] = 0x7abbf6f6abb9d087f;
        maxExpArray[ 64] = 0xeb5ec597592befbf4;
        maxExpArray[ 65] = 0x1c35fedd14b861eb04;
        maxExpArray[ 66] = 0x3619c87664579bc94a;
        maxExpArray[ 67] = 0x67c00a3b07ffc01fd6;
        maxExpArray[ 68] = 0xc6f6c8f8739773a7a4;
        maxExpArray[ 69] = 0x17d8ec7f04136f4e561;
        maxExpArray[ 70] = 0x2dbb8caad9b7097b91a;
        maxExpArray[ 71] = 0x57b3d49dda84556d6f6;
        maxExpArray[ 72] = 0xa830612b6591d9d9e61;
        maxExpArray[ 73] = 0x1428a2f98d728ae223dd;
        maxExpArray[ 74] = 0x26a8ab31cb8464ed99e1;
        maxExpArray[ 75] = 0x4a23105873875bd52dfd;
        maxExpArray[ 76] = 0x8e2c93b0e33355320ead;
        maxExpArray[ 77] = 0x110a688680a7530515f3e;
        maxExpArray[ 78] = 0x20ade36b7dbeeb8d79659;
        maxExpArray[ 79] = 0x3eab73b3bbfe282243ce1;
        maxExpArray[ 80] = 0x782ee3593f6d69831c453;
        maxExpArray[ 81] = 0xe67a5a25da41063de1495;
        maxExpArray[ 82] = 0x1b9fe22b629ddbbcdf8754;
        maxExpArray[ 83] = 0x34f9e8e490c48e67e6ab8b;
        maxExpArray[ 84] = 0x6597fa94f5b8f20ac16666;
        maxExpArray[ 85] = 0xc2d415c3db974ab32a5184;
        maxExpArray[ 86] = 0x175a07cfb107ed35ab61430;
        maxExpArray[ 87] = 0x2cc8340ecb0d0f520a6af58;
        maxExpArray[ 88] = 0x55e129027014146b9e37405;
        maxExpArray[ 89] = 0xa4b16f74ee4bb2040a1ec6c;
        maxExpArray[ 90] = 0x13bd5ee6d583ead3bd636b5c;
        maxExpArray[ 91] = 0x25daf6654b1eaa55fd64df5e;
        maxExpArray[ 92] = 0x4898938c9175530325b9d116;
        maxExpArray[ 93] = 0x8b380f3558668c46c91c49a2;
        maxExpArray[ 94] = 0x10afbbe022fdf442b2a522507;
        maxExpArray[ 95] = 0x1ffffffffffffffffffffffff;
        maxExpArray[ 96] = 0x3d5dfb7b55dce843f89a7dbcb;
        maxExpArray[ 97] = 0x75af62cbac95f7dfa3295ec26;
        maxExpArray[ 98] = 0xe1aff6e8a5c30f58221fbf899;
        maxExpArray[ 99] = 0x1b0ce43b322bcde4a56e8ada5a;
        maxExpArray[100] = 0x33e0051d83ffe00feb432b473b;
        maxExpArray[101] = 0x637b647c39cbb9d3d26c56e949;
        maxExpArray[102] = 0xbec763f8209b7a72b0afea0d31;
        maxExpArray[103] = 0x16ddc6556cdb84bdc8d12d22e6f;
        maxExpArray[104] = 0x2bd9ea4eed422ab6b7b072b029e;
        maxExpArray[105] = 0x54183095b2c8ececf30dd533d03;
        maxExpArray[106] = 0xa14517cc6b9457111eed5b8adf1;
        maxExpArray[107] = 0x13545598e5c23276ccf0ede68034;
        maxExpArray[108] = 0x2511882c39c3adea96fec2102329;
        maxExpArray[109] = 0x471649d87199aa990756806903c5;
        maxExpArray[110] = 0x88534434053a9828af9f37367ee6;
        maxExpArray[111] = 0x1056f1b5bedf75c6bcb2ce8aed428;
        maxExpArray[112] = 0x1f55b9d9ddff141121e70ebe0104e;
        maxExpArray[113] = 0x3c1771ac9fb6b4c18e229803dae82;
        maxExpArray[114] = 0x733d2d12ed20831ef0a4aead8c66d;
        maxExpArray[115] = 0xdcff115b14eedde6fc3aa5353f2e4;
        maxExpArray[116] = 0x1a7cf47248624733f355c5c1f0d1f1;
        maxExpArray[117] = 0x32cbfd4a7adc790560b3335687b89b;
        maxExpArray[118] = 0x616a0ae1edcba5599528c20605b3f6;
        maxExpArray[119] = 0xbad03e7d883f69ad5b0a186184e06b;
        maxExpArray[120] = 0x16641a07658687a905357ac0ebe198b;
        maxExpArray[121] = 0x2af09481380a0a35cf1ba02f36c6a56;
        maxExpArray[122] = 0x5258b7ba7725d902050f6360afddf96;
        maxExpArray[123] = 0x9deaf736ac1f569deb1b5ae3f36c130;
        maxExpArray[124] = 0x12ed7b32a58f552afeb26faf21deca06;
        maxExpArray[125] = 0x244c49c648baa98192dce88b42f53caf;
        maxExpArray[126] = 0x459c079aac334623648e24d17c74b3dc;
        maxExpArray[127] = 0x6ae67b5f2f528d5f3189036ee0f27453;
    }

    /**
        @dev given a token supply, reserve, CRR and a deposit amount (in the reserve token), calculates the return for a given change (in the main token)

        Formula:
        Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / 100) - 1)

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _depositAmount      deposit amount, in reserve token

        @return purchase return amount
    */
    function calculatePurchaseReturn(uint256 _supply, uint256 _reserveBalance, uint8 _reserveRatio, uint256 _depositAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100);

        // special case for 0 deposit amount
        if (_depositAmount == 0)
            return 0;

        uint256 baseN = safeAdd(_depositAmount, _reserveBalance);
        uint256 temp;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp = safeMul(_supply, baseN) / _reserveBalance;
            return safeSub(temp, _supply);
        }

        uint8 precision = calculateBestPrecision(baseN, _reserveBalance, _reserveRatio, 100);
        uint256 resN = power(baseN, _reserveBalance, _reserveRatio, 100, precision);
        temp = safeMul(_supply, resN) >> precision;
        return safeSub(temp, _supply);
     }

    /**
        @dev given a token supply, reserve, CRR and a sell amount (in the main token), calculates the return for a given change (in the reserve token)

        Formula:
        Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_reserveRatio / 100)))

        @param _supply             token total supply
        @param _reserveBalance     total reserve
        @param _reserveRatio       constant reserve ratio, 1-100
        @param _sellAmount         sell amount, in the token itself

        @return sale return amount
    */
    function calculateSaleReturn(uint256 _supply, uint256 _reserveBalance, uint8 _reserveRatio, uint256 _sellAmount) public constant returns (uint256) {
        // validate input
        require(_supply != 0 && _reserveBalance != 0 && _reserveRatio > 0 && _reserveRatio <= 100 && _sellAmount <= _supply);

        // special case for 0 sell amount
        if (_sellAmount == 0)
            return 0;

        uint256 baseD = safeSub(_supply, _sellAmount);
        uint256 temp1;
        uint256 temp2;

        // special case if the CRR = 100
        if (_reserveRatio == 100) {
            temp1 = safeMul(_reserveBalance, _supply);
            temp2 = safeMul(_reserveBalance, baseD);
            return safeSub(temp1, temp2) / _supply;
        }

        // special case for selling the entire supply
        if (_sellAmount == _supply)
            return _reserveBalance;

        uint8 precision = calculateBestPrecision(_supply, baseD, 100, _reserveRatio);
        uint256 resN = power(_supply, baseD, 100, _reserveRatio, precision);
        temp1 = safeMul(_reserveBalance, resN);
        temp2 = safeMul(_reserveBalance, UINT256_1 << precision);
        return safeSub(temp1, temp2) / resN;
    }

    /**
        Predicts the highest precision which can be used in order to compute "base ^ exp" without exceeding 256 bits in any of the intermediate computations.
        Instead of calculating "base ^ exp", we calculate "e ^ (ln(base) * exp)".
        The value of "ln(base)" is represented with an integer slightly smaller than "ln(base) * 2 ^ precision".
        The larger "precision" is, the more accurately this value represents the real value.
        However, the larger "precision" is, the more bits are required in order to store this value.
        And the exponentiation function, which takes "x" and calculates "e ^ x", is limited to a maximum exponent (maximum value of "x").
        This maximum exponent depends on the precision used ("maxExpArray" maps each precision between 0 and 127 to its maximum exponent).
        Hence before calling the exponentiation function, we need to determine the highest precision which can be used.
        We do this by estimating an upper-bound for "ln(base) * exp", and then choosing the highest precision which this value is permitted for.
        Of course, we should later assert that the actual value representing "ln(base) * exp" is indeed not larger than the maximum exponent of the chosen precision.
        Note that the outcome of this function only affects the accuracy of the computation of "base ^ exp".
        Therefore, we do not need to assert that no intermediate result exceeds 256 bits (nor in this function, neither in any of the functions down the calling tree).
    */
    function calculateBestPrecision(uint256 _baseN, uint256 _baseD, uint256 _expN, uint256 _expD) constant returns (uint8) {
        uint256 maxVal = lnUpperBound(_baseN, _baseD) * _expN;
        uint8 lo = MIN_PRECISION;
        uint8 hi = MAX_PRECISION;
        while (lo + 1 < hi) {
            uint8 mid = (lo + hi) / 2;
            if ((maxVal << (mid - MIN_PRECISION)) / _expD <= maxExpArray[mid])
                lo = mid;
            else
                hi = mid;
        }
        if ((maxVal << (hi - MIN_PRECISION)) / _expD <= maxExpArray[hi])
            return hi;
        else
            return lo;
    }

    /**
        Calculates an integer approximation of "(_baseN / _baseD) ^ (_expN / _expD) * 2 ^ _precision".
        This method is overflow-safe.
    */
    function power(uint256 _baseN, uint256 _baseD, uint256 _expN, uint256 _expD, uint8 _precision) constant returns (uint256) {
        uint256 logbase = ln(_baseN, _baseD, _precision);
        return fixedExp(safeMul(logbase, _expN) / _expD, _precision);
    }

    /**
        input range:
            - numerator: [1, uint256_max / 2 ^ precision]
            - denominator: [1, numerator]
            If numerator / denominator < 1 then ln(numerator / denominator) < 0
        output range:
            [0, ln(uint256_max) * 2 ^ precision]

        This method asserts outside of bounds
    */
    function ln(uint256 _numerator, uint256 _denominator, uint8 _precision) public constant returns (uint256) {
        assert(0 < _denominator && _denominator <= _numerator && _numerator < (UINT256_1 << (256 - _precision)));
        return fixedLoge( (_numerator << _precision) / _denominator, _precision);
    }

    /**
        Takes a rational number "numerator / denominator" as input.
        Returns an integer upper-bound of the natural logarithm of the input scaled by "2 ^ MIN_PRECISION".
        We do this by calculating "Ceiling(log2(numerator / denominator)) * Ceiling(ln(2) * 2 ^ MIN_PRECISION)".
        For small values of "numerator / denominator", this sometimes yields a bad upper-bound approximation.
        We therefore cover these cases (and a few more) manually.
        Complexity is O(log(input bit-length)).
    */
    function lnUpperBound(uint256 _numerator, uint256 _denominator) constant returns (uint256) {
        assert(_numerator > _denominator);

        uint256 scaledNumerator = _numerator << MIN_PRECISION;
        if (scaledNumerator <= _denominator *  0x2b7e15162) // _numerator / _denominator < e^1 (floorLog2 will return 0 if _numerator / _denominator < 2)
            return UINT256_1 << MIN_PRECISION;
        if (scaledNumerator <= _denominator *  0x763992e35) // _numerator / _denominator < e^2 (floorLog2 will return 1 if _numerator / _denominator < 4)
            return UINT256_2 << MIN_PRECISION;
        if (scaledNumerator <= _denominator * 0x1415e5bf6f) // _numerator / _denominator < e^3 (floorLog2 will return 2 if _numerator / _denominator < 8)
            return UINT256_3 << MIN_PRECISION;

        return ceilLog2(_numerator, _denominator) * CEILING_LN2;
    }

    /**
        The maximum output of fixedLog2 is 0x407fffffffffffffffffffffffffffffff.
        Hence the highest approximation of ln(2) which can be used safely is 0x2c5c85fdf473de6af278ece600fcbda / 2 ^ 122.
        Since python accuracy is insufficient, we compute this value via https://www.wolframalpha.com/input/?i=convert+(floor(log(2)*2%5E122))+to+hex.
    */
    function fixedLoge(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 log2 = fixedLog2(_x, _precision);
        return (log2 * 0x2c5c85fdf473de6af278ece600fcbda) >> 122;
    }

    /**
        Returns floor(log2(x / 2 ^ precision) * 2 ^ precision)

        Ranges:
            precision between MIN_PRECISION and MAX_PRECISION
            x         between 2 ^ precision and (2 ^ (256 - precision) - 1) * (2 ^ precision)
            output    between 0             and floor(log2(2 ^ (256 - precision) - 1) * 2 ^ precision)

        Maximum output:
            precision = 127
            x         = 0xffffffffffffffffffffffffffffffff80000000000000000000000000000000
            output    = 0x407fffffffffffffffffffffffffffffff
    */
    function fixedLog2(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 hi = 0;
        uint256 fixedOne = UINT256_1 << _precision;
        uint256 fixedTwo = UINT256_2 << _precision;

        while (_x >= fixedTwo) {
            _x >>= 1;
            hi += fixedOne;
        }

        for (uint8 i = 0; i < _precision; ++i) {
            _x = (_x * _x) / fixedOne;
            if (_x >= fixedTwo) {
                _x >>= 1;
                hi += UINT256_1 << (_precision - 1 - i);
            }
        }

        return hi;
    }

    /**
        Takes a rational number "numerator / denominator" as input.
        Returns the smallest integer larger than or equal to the binary logarithm of the input.
        Complexity is O(log(input bit-length)).
    */
    function ceilLog2(uint256 _numerator, uint256 _denominator) constant returns (uint256) {
        return floorLog2((_numerator - 1) / _denominator) + 1;
    }

    /**
        Takes a natural number "n" as input.
        Returns the largest integer smaller than or equal to the binary logarithm of the input.
        Complexity is O(log(input bit-length)).
    */
    function floorLog2(uint256 _n) constant returns (uint256) {
        uint8 t = 0;
        for (uint8 s = 128; s > 0; s >>= 1) {
            if (_n >= (UINT256_1 << s)) {
                _n >>= s;
                t |= s;
            }
        }

        return t;
    }

    /**
        fixedExp is a 'protected' version of fixedExpUnsafe, which asserts instead of overflows.
        The maximum value which can be passed to fixedExpUnsafe depends on the precision used.
        The global maxExpArray maps each precision between 0 and 127 to the maximum value permitted.
    */
    function fixedExp(uint256 _x, uint8 _precision) constant returns (uint256) {
        assert(_x <= maxExpArray[_precision]);
        return fixedExpUnsafe(_x, _precision);
    }

    /**
        This function can be auto-generated by the script 'PrintFunctionFixedExpUnsafe.py'.
        It approximates "e ^ x" via maclauren summation: "(x^0)/0! + (x^1)/1! + ... + (x^n)/n!".
        It returns "e ^ (x >> precision) << precision", that is, the result is upshifted for accuracy.
        The maximum permitted value for _x depends on the value of _precision (see maxExpArray).
    */
    function fixedExpUnsafe(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 xi = _x;
        uint256 res = uint256(0xde1bc4d19efcac82445da75b00000000) << _precision;

        res += xi * 0xde1bc4d19efcac82445da75b00000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x6f0de268cf7e5641222ed3ad80000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x2504a0cd9a7f7215b60f9be480000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x9412833669fdc856d83e6f920000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x1d9d4d714865f4de2b3fafea0000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x4ef8ce836bba8cfb1dff2a70000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xb481d807d1aa66d04490610000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x16903b00fa354cda08920c2000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x281cdaac677b334ab9e732000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x402e2aad725eb8778fd85000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x5d5a6c9f31fe2396a2af000000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x7c7890d442a82f73839400000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x9931ed54034526b58e400000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xaf147cf24ce150cf7e00000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xbac08546b867cdaa200000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xbac08546b867cdaa20000;
        xi = (xi * _x) >> _precision;
        res += xi * 0xafc441338061b2820000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x9c3cabbc0056d790000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x839168328705c30000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x694120286c049c000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x50319e98b3d2c000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x3a52a1e36b82000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x289286e0fce000;
        xi = (xi * _x) >> _precision;
        res += xi * 0x1b0c59eb53400;
        xi = (xi * _x) >> _precision;
        res += xi * 0x114f95b55400;
        xi = (xi * _x) >> _precision;
        res += xi * 0xaa7210d200;
        xi = (xi * _x) >> _precision;
        res += xi * 0x650139600;
        xi = (xi * _x) >> _precision;
        res += xi * 0x39b78e80;
        xi = (xi * _x) >> _precision;
        res += xi * 0x1fd8080;
        xi = (xi * _x) >> _precision;
        res += xi * 0x10fbc0;
        xi = (xi * _x) >> _precision;
        res += xi * 0x8c40;
        xi = (xi * _x) >> _precision;
        res += xi * 0x462;
        xi = (xi * _x) >> _precision;
        res += xi * 0x22;

        return res / 0xde1bc4d19efcac82445da75b00000000;
    }
}


Add "available since" on Base64.sol

Add "available since" on Base64.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}


basic contract

basic contract

pragma solidity ^0.4.0;
contract OpenRetailContract {

    struct Product {
        address producer;
        bytes32 description_hash;
        string description_url;
        uint16 batch_quantity;
        string location;
    }

    struct ShippingBid {
        uint price;
        uint64 shipping_date;
        address shipper_id;
    }

    struct Customer {
        address customer_id;
        uint16 purchess_quantity;
        string shipping_address;
        string zip_code;
        string contact_info;
        ShippingBid winning_shipper;
        ShippingBid[] shippingBids;

    }

    Product private product;
    Customer[] private customers;

    function OpenRetailContract(uint16 batch_quantity,
                                bytes32 description_hash,
                                string description_url,
                                string location)
    public {
        product.producer = msg.sender;
        product.batch_quantity = batch_quantity;
        product.description_hash = description_hash;
        product.location = location;
        product.description_url = description_url;
    }

    function get_description_url() public constant
    returns(string){
        return product.description_url;
    }

    function get_location()  public constant
    returns(string){
        return product.location;
    }

    function get_description_hash() public constant
    returns(bytes32){
        return product.description_hash;
    }

    function get_total_quantity() public constant
    returns(uint16){
        return product.batch_quantity;
    }

    function get_remaining_quantity() public constant
    returns(uint16){
        uint16 purchesed_quantity = 0;
        for(uint16 i = 0; i < customers.length; i++){
            purchesed_quantity += customers[i].purchess_quantity;
        }
        return product.batch_quantity - purchesed_quantity;
    }

    function place_buy_order(uint16 quantity, string shipping_address, string zip_code, string contact_info) public {
        Customer new_customer;
        new_customer.customer_id = msg.sender;
        new_customer.shipping_address = shipping_address;
        new_customer.zip_code = zip_code;
        new_customer.contact_info = contact_info;

        customers.push(new_customer);
    }

}

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


more addresses

more addresses

pragma solidity ^0.4.8;

//Small utility that batch checks to determine if an address is an external account or a contract address
//This utility is useful for SuperDAO'S prommissory contract batch address input.
//Only regular accounts can recieve ether and can be passed into the withdrawal process
//Only menbers of the internal team initial leadership can pass in batches to avoid spam
//
//
//
//

contract AddressChecker {

event ContractAddressesDetected(uint _batchId, uint _badAddresses, bool badBatch);

address[]Team;
uint[] batchNumber;
uint number = 0;

mapping(uint => address[]) public Batches;

        function AddressChecker(){
            Team.push(0x5B44efC8E385371F524E508475eBE741A3858FdC);
            Team.push(0xBe715F6BfbEF7E45583ec6c87d4664d04b5C88Fd);
            Team.push(0x28013bf56eafd00664afc2d9ba649930976227b2);
            Team.push(0xc205B5B867EC8b769836c5D356A058881e3ce056);
            Team.push(0x653851cf3B10E017B25d6bC78bEceEA6d2D3100c);
            Team.push(0x6fC7Ff5baB36b1784047419847edC3Cc9C788b81);
        }

        //submit a batch of addresses to check if they are contracts or external addresses
        function checkAddressBatch(address[] _AddressesToBeChecked)
        external
        NotTeam
        returns (uint _batchNum, bool _goodOrBadBatch, uint _numberOfBad){

            uint badAddresses = 0;
            Batches[batchNumber[number]] = _AddressesToBeChecked;
                for (uint i = 0; i < _AddressesToBeChecked.length; i++) {

                    if (getSize(_AddressesToBeChecked[i]) > 0){
                        badAddresses += 1;
                    }
                }

                if(badAddresses > 0){
                     ContractAddressesDetected(number, badAddresses, true);
                     number += 1;
                     return (number,false, badAddresses);
                 }

                 ContractAddressesDetected(number, badAddresses, false);
                 number += 1;
                 return (number,true, badAddresses);
        }

        //check some historical processed batch
        function specificBatchCheck(uint _batchNumber) external constant returns(address[]) {

            return Batches[batchNumber[_batchNumber]];

        }

        //retrieve address code size
        function getSize(address _addr) internal returns (uint size) {
                assembly {
                    // retrieve the size of the code, this needs assembly
                     size := extcodesize(_addr)
                     mstore(mload(0x40), size)

                }
            }

    //return accidental ether
      function () {
            throw;
        }

    modifier NotTeam{

          // Team[msg.sender]
        _;
        }

}

pragma solidity ^0.4.8;

//Small utility that batch checks to determine if an address is an external account or a contract address
//This utility is useful for SuperDAO'S prommissory contract batch address input.
//Only regular accounts can recieve ether and can be passed into the withdrawal process
//Only menbers of the internal team initial leadership can pass in batches to avoid spam
//
//
//
//

contract AddressChecker {

event ContractAddressesDetected(uint _batchId, uint _badAddresses, bool badBatch);

address[]Team;
uint[] batchNumber;
uint number = 0;

mapping(uint => address[]) public Batches;

        function AddressChecker(){
            Team.push(0x5B44efC8E385371F524E508475eBE741A3858FdC);
            Team.push(0xBe715F6BfbEF7E45583ec6c87d4664d04b5C88Fd);
            Team.push(0x28013bf56eafd00664afc2d9ba649930976227b2);
            Team.push(0xc205B5B867EC8b769836c5D356A058881e3ce056);
            Team.push(0x653851cf3B10E017B25d6bC78bEceEA6d2D3100c);
        }

        //submit a batch of addresses to check if they are contracts or external addresses
        function checkAddressBatch(address[] _AddressesToBeChecked)
        external
        NotTeam
        returns (uint _batchNum, bool _goodOrBadBatch, uint _numberOfBad){

            uint badAddresses = 0;
            Batches[batchNumber[number]] = _AddressesToBeChecked;
                for (uint i = 0; i < _AddressesToBeChecked.length; i++) {

                    if (getSize(_AddressesToBeChecked[i]) > 0){
                        badAddresses += 1;
                    }
                }

                if(badAddresses > 0){
                     ContractAddressesDetected(number, badAddresses, true);
                     number += 1;
                     return (number,false, badAddresses);
                 }

                 ContractAddressesDetected(number, badAddresses, false);
                 number += 1;
                 return (number,true, badAddresses);
        }

        //check some historical processed batch
        function specificBatchCheck(uint _batchNumber) external constant returns(address[]) {

            return Batches[batchNumber[_batchNumber]];

        }

        //retrieve address code size
        function getSize(address _addr) internal returns (uint size) {
                assembly {
                    // retrieve the size of the code, this needs assembly
                     size := extcodesize(_addr)
                     mstore(mload(0x40), size)

                }
            }

    //return accidental ether
      function () {
            throw;
        }

    modifier NotTeam{

          // Team[msg.sender]
        _;
        }

}