Fix the superAdmin's permission prob

Fix the superAdmin's permission prob

pragma solidity ^0.4.18;

import "./permission_data.sol";

/// @title The authentication of the permission system
contract PermissionCheck is PermissionData {

    /// @dev User in group
    modifier userInGroup(address _user, bytes32 _group) {
        if (_user != superAdmin)
            require(Util.addressInArray(_user, groups.groups[_group].users));
        _;
    }

    /// @dev Permission in role
    modifier permissionInRole(bytes32 _permission, bytes32 _role) {
       require(Util.bytes32InArray(_permission, roles.roles[_role].permissions));
        _;
    }

    /// @dev Permissions in role
    modifier permissionsInRole(bytes32[] _permissions, bytes32 _role) {
       require(Util.bytes32SubSet(_permissions, roles.roles[_role].permissions));
        _;
    }

    /// @dev Group has role
    modifier groupHasRole(bytes32 _group, bytes32 _role) {
        require(Util.bytes32InArray(_role, auth.group_roles[_group]));
        _;
    }

    /// @dev Resource group in zone of the user group
    /// @notice For scope. To check resourceGroup is userGroup's subGroup for now
    ///         TODO: A scope struct
    modifier resourceInZone(bytes32 _resourceGroup, bytes32 _userGroup) {
        // Need scope switch on
        require(groups.groups[_userGroup].subSwitch);
        require(Util.bytes32InArray(_resourceGroup, groups.groups[_userGroup].subGroups));
        _;
    }

    /// @dev Resource group belong user group.
    modifier resourceBelongGroup(bytes32 _resourceGroup, bytes32 _userGroup) {
        if (groups.groups[_userGroup].subSwitch)
            // Scope switch is on
            require(Util.bytes32InArray(_resourceGroup, groups.groups[_userGroup].subGroups));
        else
            // Scope switch is off
            require(_resourceGroup == _userGroup);
        _;
    }

    /// @dev Name does not exist
    modifier nameNotExist(bytes32 _name, bytes32[] _names) {
        require(!Util.bytes32InArray(_name, _names));
        _;
    }

    /// @dev Name exists
    modifier nameExist(bytes32 _name, bytes32[] _names) {
        require(Util.bytes32InArray(_name, _names));
        _;
    }

    /// @dev Leaf node
    modifier leafNode(bytes32 _group) {
        require(Util.bytes32ArrayNul(groups.groups[_group].subGroups));
        _;
    }

    /// @dev Only superAdmin
    modifier onlySuperAdmin {
        require(msg.sender == superAdmin);
        _;
    }

    /// @dev Group is null
    modifier groupNul(bytes32 _group) {
        require(bytes32(0x0) == groups.groups[_group].name);
        require(Util.addressArrayNul(groups.groups[_group].users));
        require(Util.bytes32ArrayNul(groups.groups[_group].subGroups));
        require(false == groups.groups[_group].subSwitch);
        require(Util.bytes32ArrayNul(auth.group_roles[_group]));
        _;
    }

    /// @dev Role is null
    modifier roleNul(bytes32 _role) {
        require(bytes32(0x0) == roles.roles[_role].name);
        require(Util.bytes32ArrayNul(roles.roles[_role].permissions));
        require(Util.bytes32ArrayNul(auth.role_groups[_role]));
        _;
    }

    /// @dev Authorization is null
    modifier authNul(bytes32 _group, bytes32 _role) {
        require(Util.bytes32ArrayNul(auth.role_groups[_role]));
        require(Util.bytes32ArrayNul(auth.group_roles[_group]));
        _;
    }

    /// @dev Can do
    modifier can(
        address _user,
        bytes32 _userGroup,
        bytes32 _resourceGroup,
        bytes32 _role,
        bytes32 _permission
    ) {
        if (_user != superAdmin)
            require(check(_user, _userGroup, _resourceGroup, _role , _permission));
        _;
    }

    /// @dev Check user group has the permission with the scope of the resource group
    /// @notice For external function calls
    function check(
        address _user,
        bytes32 _userGroup,
        bytes32 _resourceGroup,
        bytes32 _role,
        bytes32 _permission
    )
        view
        public
        userInGroup(_user, _userGroup)
        groupHasRole(_userGroup, _role)
        permissionInRole(_permission, _role)
        resourceBelongGroup(_resourceGroup, _userGroup)
        returns (bool)
    {
        return true;
    }
}

pragma solidity ^0.4.18;

import "./permission_data.sol";

/// @title The authentication of the permission system
contract PermissionCheck is PermissionData {

    /// @dev User in group
    modifier userInGroup(address _user, bytes32 _group) {
        if (_user != superAdmin)
            require(Util.addressInArray(_user, groups.groups[_group].users));
        _;
    }

    /// @dev Permission in role
    modifier permissionInRole(bytes32 _permission, bytes32 _role) {
       require(Util.bytes32InArray(_permission, roles.roles[_role].permissions));
        _;
    }

    /// @dev Permissions in role
    modifier permissionsInRole(bytes32[] _permissions, bytes32 _role) {
       require(Util.bytes32SubSet(_permissions, roles.roles[_role].permissions));
        _;
    }

    /// @dev Group has role
    modifier groupHasRole(bytes32 _group, bytes32 _role) {
        require(Util.bytes32InArray(_role, auth.group_roles[_group]));
        _;
    }

    /// @dev Resource group in zone of the user group
    /// @notice For scope. To check resourceGroup is userGroup's subGroup for now
    ///         TODO: A scope struct
    modifier resourceInZone(bytes32 _resourceGroup, bytes32 _userGroup) {
        // Need scope switch on
        require(groups.groups[_userGroup].subSwitch);
        require(Util.bytes32InArray(_resourceGroup, groups.groups[_userGroup].subGroups));
        _;
    }

    /// @dev Resource group belong user group.
    modifier resourceBelongGroup(bytes32 _resourceGroup, bytes32 _userGroup) {
        if (groups.groups[_userGroup].subSwitch)
            // Scope switch is on
            require(Util.bytes32InArray(_resourceGroup, groups.groups[_userGroup].subGroups));
        else
            // Scope switch is off
            require(_resourceGroup == _userGroup);
        _;
    }

    /// @dev Name does not exist
    modifier nameNotExist(bytes32 _name, bytes32[] _names) {
        require(!Util.bytes32InArray(_name, _names));
        _;
    }

    /// @dev Name exists
    modifier nameExist(bytes32 _name, bytes32[] _names) {
        require(Util.bytes32InArray(_name, _names));
        _;
    }

    /// @dev Leaf node
    modifier leafNode(bytes32 _group) {
        require(Util.bytes32ArrayNul(groups.groups[_group].subGroups));
        _;
    }

    /// @dev Only superAdmin
    modifier onlySuperAdmin {
        require(msg.sender == superAdmin);
        _;
    }

    /// @dev Group is null
    modifier groupNul(bytes32 _group) {
        require(bytes32(0x0) == groups.groups[_group].name);
        require(Util.addressArrayNul(groups.groups[_group].users));
        require(Util.bytes32ArrayNul(groups.groups[_group].subGroups));
        require(false == groups.groups[_group].subSwitch);
        require(Util.bytes32ArrayNul(auth.group_roles[_group]));
        _;
    }

    /// @dev Role is null
    modifier roleNul(bytes32 _role) {
        require(bytes32(0x0) == roles.roles[_role].name);
        require(Util.bytes32ArrayNul(roles.roles[_role].permissions));
        require(Util.bytes32ArrayNul(auth.role_groups[_role]));
        _;
    }

    /// @dev Authorization is null
    modifier authNul(bytes32 _group, bytes32 _role) {
        require(Util.bytes32ArrayNul(auth.role_groups[_role]));
        require(Util.bytes32ArrayNul(auth.group_roles[_group]));
        _;
    }

    /// @dev Can do
    modifier can(
        address _user,
        bytes32 _userGroup,
        bytes32 _resourceGroup,
        bytes32 _role,
        bytes32 _permission
    ) {
        require(check(_user, _userGroup, _resourceGroup, _role , _permission));
        _;
    }

    /// @dev Check user group has the permission with the scope of the resource group
    /// @notice For external function calls
    function check(
        address _user,
        bytes32 _userGroup,
        bytes32 _resourceGroup,
        bytes32 _role,
        bytes32 _permission
    )
        view
        public
        userInGroup(_user, _userGroup)
        groupHasRole(_userGroup, _role)
        permissionInRole(_permission, _role)
        resourceBelongGroup(_resourceGroup, _userGroup)
        returns (bool)
    {
        return true;
    }
}


Minor correction.

Minor correction.

//sol Registrar
// Simple global registrar.
// @authors:
//   Gav Wood <g@ethdev.com>

contract NameRegister {
	function getAddress(string32 _name) constant returns (address o_owner) {}
	function getName(address _owner) constant returns (string32 o_name) {}
}

contract Register is NameRegister {
	function getOwner(string32 _name) constant returns (address o_owner) {}
	function getAddress(string32 _name) constant returns (address o_address) {}
	function getRegister(string32 _name) constant returns (Register o_register) {}
	function getContent(string32 _name) constant returns (hash o_content) {}

	function getName(address _owner) constant returns (string32 o_name) {}
}

contract Registrar is Register {
	struct Record {
		address owner;
		address primary;
		Register registrar;
		hash content;
	}

	function Registrar() {
		// TODO: Populate with hall-of-fame.
	}

	function reserve(string32 _name) {
		// Don't allow the same name to be overwritten.
		if (m_toRecord[_name].owner == 0) {
			m_toRecord[_name].primary = msg.sender;
			// TODO: Log
		}
	}

	function transfer(string32 _name, address _newOwner) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].owner = _newOwner;
			// TODO: Log
		}
	}

	function unregister(string32 _name) {
		if (m_toRecord[_name].owner == msg.sender) {
			if (m_toName[m_toRecord[_name].primary] == _name)
				m_toName[m_toRecord[_name].primary] = "";
			delete m_toRecord[_name];
			// TODO: Log
		}
	}

	function setAddress(string32 _name, address _a, bool _primary) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].primary = _a;
			if (_primary)
				m_toName[_a] = _name;
			// TODO: Log
		}
	}
	function setRegister(string32 _name, Register _registrar) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].registrar = _registrar;
			// TODO: Log
		}
	}
	function setContent(string32 _name, hash _content) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].content = _content;
			// TODO: Log
		}
	}

	// TODO....
	function getRecord(string32 _name) constant returns (address o_owner, address o_primary, Register o_registrar, hash o_content) {
		o_owner = m_toRecord[_name].owner;
		o_primary = m_toRecord[_name].primary;
		o_registrar = m_toRecord[_name].registrar;
		o_content = m_toRecord[_name].content;
	}
	function getOwner(string32 _name) constant returns (address o_owner) { o_owner = m_toRecord[_name].owner; }
	function getAddress(string32 _name) constant returns (address o_bene) { o_bene = m_toRecord[_name].primary; }
	function getRegister(string32 _name) constant returns (Register o_registrar) { o_registrar = m_toRecord[_name].registrar; }
	function getContent(string32 _name) constant returns (hash o_content) { o_content = m_toRecord[_name].content; }

	function getName(address _owner) constant returns (string32 o_name) { o_name = m_toName[_owner]; }

/*	logentry MoreLog {
		index uint l;
		index uint m;
		hash x;
		uint z;
	}*/

	mapping (address => string32) m_toName;
	mapping (string32 => Record) m_toRecord;
}

/*

[{"constant":false,"inputs":[{"name":"_name","type":"string32"}],"name":"reserve","outputs":[]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getRecord","outputs":[{"name":"o_owner","type":"address"},{"name":"o_primary","type":"address"},{"name":"o_registrar","type":"contractRegister"},{"name":"o_content","type":"hash256"}]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_content","type":"hash256"}],"name":"setContent","outputs":[]},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getName","outputs":[{"name":"o_name","type":"string32"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getBeneficiary","outputs":[{"name":"o_owner","type":"address"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getRegister","outputs":[{"name":"o_registrar","type":"contractRegister"}]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_registrar","type":"contractRegister"}],"name":"setRegister","outputs":[]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setBeneficiary","outputs":[]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getContent","outputs":[{"name":"o_content","type":"hash256"}]},{"constant":false,"inputs":[{"name":"_name","type":"string32"}],"name":"unregister","outputs":[]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getAddress","outputs":[{"name":"o_bene","type":"address"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getOwner","outputs":[{"name":"o_owner","type":"address"}]}]

contract Registrar{function reserve(string32 _name){}function getRecord(string32 _name)constant returns(address o_owner,address o_primary,contract Register o_registrar,hash256 o_content){}function setContent(string32 _name,hash256 _content){}function getName(address _owner)constant returns(string32 o_name){}function getBeneficiary(string32 _name)constant returns(address o_owner){}function getRegister(string32 _name)constant returns(contract Register o_registrar){}function setRegister(string32 _name,contract Register _registrar){}function setBeneficiary(string32 _name,address _a,bool _primary){}function transfer(string32 _name,address _newOwner){}function getContent(string32 _name)constant returns(hash256 o_content){}function unregister(string32 _name){}function getAddress(string32 _name)constant returns(address o_bene){}function getOwner(string32 _name)constant returns(address o_owner){}}

*/

//sol Registrar
// Simple global registrar.
// @authors:
//   Gav Wood <g@ethdev.com>

contract NameRegister {
	function getAddress(string32 _name) constant returns (address o_owner) {}
	function getName(address _owner) constant returns (string32 o_name) {}
}

contract Register is NameRegister {
	function getAddress(string32 _name) constant returns (address o_owner) {}
	function getBeneficiary(string32 _name) constant returns (address o_owner) {}
	function getRegister(string32 _name) constant returns (Register o_register) {}
	function getContent(string32 _name) constant returns (hash o_content) {}

	function getName(address _owner) constant returns (string32 o_name) {}
}

contract Registrar is Register {
	struct Record {
		address owner;
		address primary;
		Register registrar;
		hash content;
	}

	function Registrar() {
		// TODO: Populate with hall-of-fame.
	}

	function reserve(string32 _name) {
		// Don't allow the same name to be overwritten.
		if (m_toRecord[_name].owner == 0) {
			m_toRecord[_name].primary = msg.sender;
			// TODO: Log
		}
	}

	function transfer(string32 _name, address _newOwner) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].owner = _newOwner;
			// TODO: Log
		}
	}

	function unregister(string32 _name) {
		if (m_toRecord[_name].owner == msg.sender) {
			if (m_toName[m_toRecord[_name].primary] == _name)
				m_toName[m_toRecord[_name].primary] = "";
			delete m_toRecord[_name];
			// TODO: Log
		}
	}

	function setBeneficiary(string32 _name, address _a, bool _primary) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].primary = _a;
			if (_primary)
				m_toName[_a] = _name;
			// TODO: Log
		}
	}
	function setRegister(string32 _name, Register _registrar) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].registrar = _registrar;
			// TODO: Log
		}
	}
	function setContent(string32 _name, hash _content) {
		if (m_toRecord[_name].owner == msg.sender) {
			m_toRecord[_name].content = _content;
			// TODO: Log
		}
	}

	// TODO....
	function getRecord(string32 _name) constant returns (address o_owner, address o_primary, Register o_registrar, hash o_content) {
		o_owner = m_toRecord[_name].owner;
		o_primary = m_toRecord[_name].primary;
		o_registrar = m_toRecord[_name].registrar;
		o_content = m_toRecord[_name].content;
	}
	function getOwner(string32 _name) constant returns (address o_owner) { o_owner = m_toRecord[_name].owner; }
	function getAddress(string32 _name) constant returns (address o_bene) { o_bene = m_toRecord[_name].primary; }
	function getRegister(string32 _name) constant returns (Register o_registrar) { o_registrar = m_toRecord[_name].registrar; }
	function getContent(string32 _name) constant returns (hash o_content) { o_content = m_toRecord[_name].content; }

	function getName(address _owner) constant returns (string32 o_name) { o_name = m_toName[_owner]; }

/*	logentry MoreLog {
		index uint l;
		index uint m;
		hash x;
		uint z;
	}*/

	mapping (address => string32) m_toName;
	mapping (string32 => Record) m_toRecord;
}

/*

[{"constant":false,"inputs":[{"name":"_name","type":"string32"}],"name":"reserve","outputs":[]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getRecord","outputs":[{"name":"o_owner","type":"address"},{"name":"o_primary","type":"address"},{"name":"o_registrar","type":"contractRegister"},{"name":"o_content","type":"hash256"}]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_content","type":"hash256"}],"name":"setContent","outputs":[]},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getName","outputs":[{"name":"o_name","type":"string32"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getBeneficiary","outputs":[{"name":"o_owner","type":"address"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getRegister","outputs":[{"name":"o_registrar","type":"contractRegister"}]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_registrar","type":"contractRegister"}],"name":"setRegister","outputs":[]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_a","type":"address"},{"name":"_primary","type":"bool"}],"name":"setBeneficiary","outputs":[]},{"constant":false,"inputs":[{"name":"_name","type":"string32"},{"name":"_newOwner","type":"address"}],"name":"transfer","outputs":[]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getContent","outputs":[{"name":"o_content","type":"hash256"}]},{"constant":false,"inputs":[{"name":"_name","type":"string32"}],"name":"unregister","outputs":[]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getAddress","outputs":[{"name":"o_bene","type":"address"}]},{"constant":true,"inputs":[{"name":"_name","type":"string32"}],"name":"getOwner","outputs":[{"name":"o_owner","type":"address"}]}]

contract Registrar{function reserve(string32 _name){}function getRecord(string32 _name)constant returns(address o_owner,address o_primary,contract Register o_registrar,hash256 o_content){}function setContent(string32 _name,hash256 _content){}function getName(address _owner)constant returns(string32 o_name){}function getBeneficiary(string32 _name)constant returns(address o_owner){}function getRegister(string32 _name)constant returns(contract Register o_registrar){}function setRegister(string32 _name,contract Register _registrar){}function setBeneficiary(string32 _name,address _a,bool _primary){}function transfer(string32 _name,address _newOwner){}function getContent(string32 _name)constant returns(hash256 o_content){}function unregister(string32 _name){}function getAddress(string32 _name)constant returns(address o_bene){}function getOwner(string32 _name)constant returns(address o_owner){}}

*/


Fix AssertIntArray.sol

Fix AssertIntArray.sol

//SPDX-License-Identifier: MIT
pragma solidity >= 0.4.15 < 0.9.0;

library AssertIntArray {

    uint8 constant ZERO = uint8(bytes1('0'));
    uint8 constant A = uint8(bytes1('a'));

    bytes1 constant MINUS = bytes1('-');

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** int[] **************************************

    /*
        Function: equal(int[])

        Assert that two 'int[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (int[]) - The first array.
            B (int[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(int[] memory arrA, int[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(int[])

        Assert that two 'int[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (int[]) - The first string.
            B (int[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(int[] memory arrA, int[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(int[])

        Assert that the length of an 'int[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (int[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(int[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(int[])

        Assert that the length of an 'int[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (int[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(int[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _itoa

        Convert a signed integer to a string. Negative numbers gets a '-' in front, e.g. "-54".

        Params:
            n (int) - The integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _itoa(int n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        bool neg = false;
        if (n < 0) {
            n = -n;
            neg = true;
        }
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        uint size = i;
        uint j = 0;
        bytes memory rev;
        if (neg) {
            size++;
            j = 1;
            rev = new bytes(size);
            rev[0] = MINUS;
        }
        else
            rev = new bytes(size);

        for (; j < size; j++)
            rev[j] = bts[size - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (bytes1) {
        if (u < 10)
            return bytes1(u + ZERO);
        else if (u < 16)
            return bytes1(u - 10 + A);
        else
            return 0;
    }

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(int)

        Add a tag to an int.

        Params:
            value (int) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _itoa(value)"
    */
    function _tag(int value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _itoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}

//SPDX-License-Identifier: MIT
pragma solidity >= 0.4.15 < 0.9.0;

library AssertIntArray {

    uint8 constant ZERO = uint8(byte('0'));
    uint8 constant A = uint8(byte('a'));

    byte constant MINUS = byte('-');

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** int[] **************************************

    /*
        Function: equal(int[])

        Assert that two 'int[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (int[]) - The first array.
            B (int[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(int[] memory arrA, int[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(int[])

        Assert that two 'int[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (int[]) - The first string.
            B (int[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(int[] memory arrA, int[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(int[])

        Assert that the length of an 'int[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (int[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(int[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(int[])

        Assert that the length of an 'int[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (int[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(int[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _itoa

        Convert a signed integer to a string. Negative numbers gets a '-' in front, e.g. "-54".

        Params:
            n (int) - The integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _itoa(int n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        bool neg = false;
        if (n < 0) {
            n = -n;
            neg = true;
        }
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        uint size = i;
        uint j = 0;
        bytes memory rev;
        if (neg) {
            size++;
            j = 1;
            rev = new bytes(size);
            rev[0] = MINUS;
        }
        else
            rev = new bytes(size);

        for (; j < size; j++)
            rev[j] = bts[size - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (byte) {
        if (u < 10)
            return byte(u + ZERO);
        else if (u < 16)
            return byte(u - 10 + A);
        else
            return 0;
    }

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(int)

        Add a tag to an int.

        Params:
            value (int) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _itoa(value)"
    */
    function _tag(int value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _itoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}


Use global constants instead of uint256(1) and uint256(2)

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

/*
    Open issues:
    - The formula is not yet super accurate, especially for very small/very high ratios
    - Improve dynamic precision support
*/

contract BancorFormula is IBancorFormula, SafeMath {

    uint256 constant ONE = 1;
    uint256 constant TWO = 2;
    uint256 constant MAX_FIXED_EXP_32 = 0x386bfdba29;
    string public version = '0.2';

    function BancorFormula() {
    }

    /**
        @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, ONE << precision);
        return safeSub(temp1, temp2) / resN;
    }

    /**
        calculateBestPrecision
        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 the precision is, the more accurately this value represents the real value.
        However, function fixedExpUnsafe(x), which calculates e ^ x, is limited to a maximum value of x.
        The limit depends on the precision (e.g, for precision = 32, the maximum value of x is MAX_FIXED_EXP_32).
        Hence before calling the 'power' function, we need to estimate an upper-bound for ln(base) * exponent.
        Of course, we should later assert that the value passed to fixedExpUnsafe is not larger than MAX_FIXED_EXP(precision).
        Due to this assertion (made in function fixedExp), functions calculateBestPrecision and fixedExp are tightly coupled.
        Note that the outcome of this function only affects the accuracy of the computation of "base ^ exp".
        Therefore, there is no 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) {
        uint8 precision;
        uint256 maxExp = MAX_FIXED_EXP_32;
        uint256 maxVal = _expN * lnUpperBound(_baseN,_baseD);
        for (precision = 32; precision < 64; precision += 2) {
            if (maxExp < (maxVal << precision) / _expD)
                break;
            maxExp = (maxExp * 0xeb5ec5975959c565) >> (64-2);
        }
        if (precision == 32)
            return 32;
        return precision-2;
    }

    /**
        @dev calculates (_baseN / _baseD) ^ (_expN / _expD)
        Returns result upshifted by precision

        This method is overflow-safe
    */
    function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD, uint8 _precision) constant returns (uint256 resN) {
        uint256 logbase = ln(_baseN, _baseD, _precision);
        // Not using safeDiv here, since safeDiv protects against
        // precision loss. It's unavoidable, however
        // Both `ln` and `fixedExp` are overflow-safe.
        resN = fixedExp(safeMul(logbase, _expN) / _expD, _precision);
        return resN;
    }

    /**
        input range:
            - numerator: [1, uint256_max >> precision]
            - denominator: [1, uint256_max >> precision]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function ln(uint256 _numerator, uint256 _denominator, uint8 _precision) public constant returns (uint256) {
        // denominator > numerator: less than one yields negative values. Unsupported
        assert(_denominator <= _numerator);

        // log(1) is the lowest we can go
        assert(_denominator != 0 && _numerator != 0);

        // Upper bits are scaled off by precision
        uint256 MAX_VAL = ONE << (256 - _precision);
        assert(_numerator < MAX_VAL);
        assert(_denominator < MAX_VAL);

        return fixedLoge( (_numerator << _precision) / _denominator, _precision);
    }

    /**
        lnUpperBound
        Takes a rational number (baseN / baseD) as input.
        Returns an estimated upper-bound integer of the natural logarithm of the input.
        We can generally use floorLog2, although there is possibly a tighter bound.
        We cannot use floorLog2 when the input is smaller than 8.
        Complexity is O(log(input bit - length)).
    */
    function lnUpperBound(uint256 _baseN, uint256 _baseD) constant returns (uint256) {
        assert(_baseN > _baseD);

        uint256 scaledBaseN = _baseN * 100000;
        if (scaledBaseN <= _baseD *  271828) // _baseN / _baseD < e^1 (floorLog2 will return 0 if _baseN / _baseD < 2)
            return 1;
        if (scaledBaseN <= _baseD *  738905) // _baseN / _baseD < e^2 (floorLog2 will return 1 if _baseN / _baseD < 4)
            return 2;
        if (scaledBaseN <= _baseD * 2008553) // _baseN / _baseD < e^3 (floorLog2 will return 2 if _baseN / _baseD < 8)
            return 3;

        return ((floorLog2((_baseN - 1) / _baseD) + 1) * 0xb17217f7d1cf78 + (1 << 56) - 1) >> 56; // ceiling(ceiling(log2(base)) * logE(2)))
    }

    /**
        input range:
            [0x100000000, uint256_max]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function fixedLoge(uint256 _x, uint8 _precision) constant returns (uint256 logE) {
        /*
        Since `fixedLog2_min` output range is max `0xdfffffffff`
        (40 bits, or 5 bytes), we can use a very large approximation
        for `ln(2)`. This one is used since it's the max accuracy
        of Python `ln(2)`

        0xb17217f7d1cf78 = ln(2) * (1 << 56)

        */
        //Cannot represent negative numbers (below 1)
        assert(_x >= ONE << _precision);

        uint256 log2 = fixedLog2(_x, _precision);
        logE = (log2 * 0xb17217f7d1cf78) >> 56;
    }

    /**
        Returns log2(x >> 32) << 32 [1]
        So x is assumed to be already upshifted 32 bits, and
        the result is also upshifted 32 bits.

        [1] The function returns a number which is lower than the
        actual value

        input-range :
            [0x100000000, uint256_max]
        output-range:
            [0,0xdfffffffff]

        This method asserts outside of bounds

    */
    function fixedLog2(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 fixedOne = ONE << _precision;
        uint256 fixedTwo = TWO << _precision;

        // Numbers below 1 are negative.
        assert( _x >= fixedOne);

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

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

        return hi;
    }

    /**
        floorLog2
        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 >= (ONE << 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 following array maps each precision between 0 and 63 to the maximum value permitted:
        maxExpArray = {
            0xc1               ,0x17a              ,0x2e5              ,0x5ab              ,
            0xb1b              ,0x15bf             ,0x2a0c             ,0x50a2             ,
            0x9aa2             ,0x1288c            ,0x238b2            ,0x4429a            ,
            0x82b78            ,0xfaadc            ,0x1e0bb8           ,0x399e96           ,
            0x6e7f88           ,0xd3e7a3           ,0x1965fea          ,0x30b5057          ,
            0x5d681f3          ,0xb320d03          ,0x15784a40         ,0x292c5bdd         ,
            0x4ef57b9b         ,0x976bd995         ,0x122624e32        ,0x22ce03cd5        ,
            0x42beef808        ,0x7ffffffff        ,0xf577eded5        ,0x1d6bd8b2eb       ,
            0x386bfdba29       ,0x6c3390ecc8       ,0xcf8014760f       ,0x18ded91f0e7      ,
            0x2fb1d8fe082      ,0x5b771955b36      ,0xaf67a93bb50      ,0x15060c256cb2     ,
            0x285145f31ae5     ,0x4d5156639708     ,0x944620b0e70e     ,0x11c592761c666    ,
            0x2214d10d014ea    ,0x415bc6d6fb7dd    ,0x7d56e76777fc5    ,0xf05dc6b27edad    ,
            0x1ccf4b44bb4820   ,0x373fc456c53bb7   ,0x69f3d1c921891c   ,0xcb2ff529eb71e4   ,
            0x185a82b87b72e95  ,0x2eb40f9f620fda6  ,0x5990681d961a1ea  ,0xabc25204e02828d  ,
            0x14962dee9dc97640 ,0x277abdcdab07d5a7 ,0x4bb5ecca963d54ab ,0x9131271922eaa606 ,
            0x116701e6ab0cd188d,0x215f77c045fbe8856,0x3ffffffffffffffff,0x7abbf6f6abb9d087f,
        };
        Since we cannot use an array of constants, we need to approximate the maximum value dynamically.
        For a precision of 32, the maximum value permitted is MAX_FIXED_EXP_32.
        For each additional precision unit, the maximum value permitted increases by approximately 1.9.
        So in order to calculate it, we need to multiply MAX_FIXED_EXP_32 by 1.9 for every additional precision unit.
        And in order to optimize for speed, we multiply MAX_FIXED_EXP_32 by 1.9^2 for every 2 additional precision units.
        Hence the general function for mapping a given precision to the maximum value permitted is:
        - precision = [32, 34, 36, ..., 62]
        - MaxFixedExp(precision) = MAX_FIXED_EXP_32 * 3.61 ^ (precision / 2 - 16)
        Since we cannot use non-integers, we do MAX_FIXED_EXP_32 * 361 ^ (precision / 2 - 16) / 100 ^ (precision / 2 - 16).
        But there is a better approximation, because this "1.9" factor in fact extends beyond a single decimal digit.
        So instead, we use 0xeb5ec5975959c565 / 0x4000000000000000, which yields maximum values quite close to real ones:
        maxExpArray = {
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            0x386bfdba29       ,-------------------,0xcf8014760e       ,-------------------,
            0x2fb1d8fe07b      ,-------------------,0xaf67a93bb37      ,-------------------,
            0x285145f31a8f     ,-------------------,0x944620b0e5ee     ,-------------------,
            0x2214d10d0112e    ,-------------------,0x7d56e7677738e    ,-------------------,
            0x1ccf4b44bb20d0   ,-------------------,0x69f3d1c9210d27   ,-------------------,
            0x185a82b87b5b294  ,-------------------,0x5990681d95d4371  ,-------------------,
            0x14962dee9dbd672b ,-------------------,0x4bb5ecca961fb9bf ,-------------------,
            0x116701e6ab0967080,-------------------,0x3fffffffffffe6652,-------------------,
        };
    */
    function fixedExp(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 maxExp = MAX_FIXED_EXP_32;
        for (uint8 p = 32; p < _precision; p += 2)
            maxExp = (maxExp * 0xeb5ec5975959c565) >> (64-2);

        assert(_x <= maxExp);
        return fixedExpUnsafe(_x, _precision);
    }

    /**
        fixedExp
        Calculates e ^ x according to maclauren summation:

        e^x = 1 + x + x ^ 2 / 2!...+ x ^ n / n!

        and returns e ^ (x >> 32) << 32, that is, upshifted for accuracy

        Input range:
            - Function ok at    <= 242329958953
            - Function fails at >= 242329958954

        This method is is visible for testcases, but not meant for direct use.

        The values in this method been generated via the following python snippet:

        def calculateFactorials():
            """Method to print out the factorials for fixedExp"""

            ni = []
            ni.append(295232799039604140847618609643520000000) # 34!
            ITERATIONS = 34
            for n in range(1, ITERATIONS, 1) :
                ni.append(math.floor(ni[n - 1] / n))
            print( "\n        ".join(["xi = (xi * _x) >> _precision;\n        res += xi * %s;" % hex(int(x)) for x in ni]))

    */
    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';

/*
    Open issues:
    - The formula is not yet super accurate, especially for very small/very high ratios
    - Improve dynamic precision support
*/

contract BancorFormula is IBancorFormula, SafeMath {

    uint256 constant MAX_FIXED_EXP_32 = 0x386bfdba29;
    string public version = '0.2';

    function BancorFormula() {
    }

    /**
        @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;
    }

    /**
        calculateBestPrecision
        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 the precision is, the more accurately this value represents the real value.
        However, function fixedExpUnsafe(x), which calculates e ^ x, is limited to a maximum value of x.
        The limit depends on the precision (e.g, for precision = 32, the maximum value of x is MAX_FIXED_EXP_32).
        Hence before calling the 'power' function, we need to estimate an upper-bound for ln(base) * exponent.
        Of course, we should later assert that the value passed to fixedExpUnsafe is not larger than MAX_FIXED_EXP(precision).
        Due to this assertion (made in function fixedExp), functions calculateBestPrecision and fixedExp are tightly coupled.
        Note that the outcome of this function only affects the accuracy of the computation of "base ^ exp".
        Therefore, there is no 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) {
        uint8 precision;
        uint256 maxExp = MAX_FIXED_EXP_32;
        uint256 maxVal = _expN * lnUpperBound(_baseN,_baseD);
        for (precision = 32; precision < 64; precision += 2) {
            if (maxExp < (maxVal << precision) / _expD)
                break;
            maxExp = (maxExp * 0xeb5ec5975959c565) >> (64-2);
        }
        if (precision == 32)
            return 32;
        return precision-2;
    }

    /**
        @dev calculates (_baseN / _baseD) ^ (_expN / _expD)
        Returns result upshifted by precision

        This method is overflow-safe
    */
    function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD, uint8 _precision) constant returns (uint256 resN) {
        uint256 logbase = ln(_baseN, _baseD, _precision);
        // Not using safeDiv here, since safeDiv protects against
        // precision loss. It's unavoidable, however
        // Both `ln` and `fixedExp` are overflow-safe.
        resN = fixedExp(safeMul(logbase, _expN) / _expD, _precision);
        return resN;
    }

    /**
        input range:
            - numerator: [1, uint256_max >> precision]
            - denominator: [1, uint256_max >> precision]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function ln(uint256 _numerator, uint256 _denominator, uint8 _precision) public constant returns (uint256) {
        // denominator > numerator: less than one yields negative values. Unsupported
        assert(_denominator <= _numerator);

        // log(1) is the lowest we can go
        assert(_denominator != 0 && _numerator != 0);

        // Upper bits are scaled off by precision
        uint256 MAX_VAL = uint256(1) << (256 - _precision);
        assert(_numerator < MAX_VAL);
        assert(_denominator < MAX_VAL);

        return fixedLoge( (_numerator << _precision) / _denominator, _precision);
    }

    /**
        lnUpperBound
        Takes a rational number (baseN / baseD) as input.
        Returns an estimated upper-bound integer of the natural logarithm of the input.
        We can generally use floorLog2, although there is possibly a tighter bound.
        We cannot use floorLog2 when the input is smaller than 8.
        Complexity is O(log(input bit - length)).
    */
    function lnUpperBound(uint256 _baseN, uint256 _baseD) constant returns (uint256) {
        assert(_baseN > _baseD);

        uint256 scaledBaseN = _baseN * 100000;
        if (scaledBaseN <= _baseD *  271828) // _baseN / _baseD < e^1 (floorLog2 will return 0 if _baseN / _baseD < 2)
            return 1;
        if (scaledBaseN <= _baseD *  738905) // _baseN / _baseD < e^2 (floorLog2 will return 1 if _baseN / _baseD < 4)
            return 2;
        if (scaledBaseN <= _baseD * 2008553) // _baseN / _baseD < e^3 (floorLog2 will return 2 if _baseN / _baseD < 8)
            return 3;

        return ((floorLog2((_baseN - 1) / _baseD) + 1) * 0xb17217f7d1cf78 + (1 << 56) - 1) >> 56; // ceiling(ceiling(log2(base)) * logE(2)))
    }

    /**
        input range:
            [0x100000000, uint256_max]
        output range:
            [0, 0x9b43d4f8d6]

        This method asserts outside of bounds

    */
    function fixedLoge(uint256 _x, uint8 _precision) constant returns (uint256 logE) {
        /*
        Since `fixedLog2_min` output range is max `0xdfffffffff`
        (40 bits, or 5 bytes), we can use a very large approximation
        for `ln(2)`. This one is used since it's the max accuracy
        of Python `ln(2)`

        0xb17217f7d1cf78 = ln(2) * (1 << 56)

        */
        //Cannot represent negative numbers (below 1)
        assert(_x >= uint256(1) << _precision);

        uint256 log2 = fixedLog2(_x, _precision);
        logE = (log2 * 0xb17217f7d1cf78) >> 56;
    }

    /**
        Returns log2(x >> 32) << 32 [1]
        So x is assumed to be already upshifted 32 bits, and
        the result is also upshifted 32 bits.

        [1] The function returns a number which is lower than the
        actual value

        input-range :
            [0x100000000, uint256_max]
        output-range:
            [0,0xdfffffffff]

        This method asserts outside of bounds

    */
    function fixedLog2(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 fixedOne = uint256(1) << _precision;
        uint256 fixedTwo = uint256(2) << _precision;

        // Numbers below 1 are negative.
        assert( _x >= fixedOne);

        uint256 hi = 0;
        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;
    }

    /**
        floorLog2
        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 following array maps each precision between 0 and 63 to the maximum value permitted:
        maxExpArray = {
            0xc1               ,0x17a              ,0x2e5              ,0x5ab              ,
            0xb1b              ,0x15bf             ,0x2a0c             ,0x50a2             ,
            0x9aa2             ,0x1288c            ,0x238b2            ,0x4429a            ,
            0x82b78            ,0xfaadc            ,0x1e0bb8           ,0x399e96           ,
            0x6e7f88           ,0xd3e7a3           ,0x1965fea          ,0x30b5057          ,
            0x5d681f3          ,0xb320d03          ,0x15784a40         ,0x292c5bdd         ,
            0x4ef57b9b         ,0x976bd995         ,0x122624e32        ,0x22ce03cd5        ,
            0x42beef808        ,0x7ffffffff        ,0xf577eded5        ,0x1d6bd8b2eb       ,
            0x386bfdba29       ,0x6c3390ecc8       ,0xcf8014760f       ,0x18ded91f0e7      ,
            0x2fb1d8fe082      ,0x5b771955b36      ,0xaf67a93bb50      ,0x15060c256cb2     ,
            0x285145f31ae5     ,0x4d5156639708     ,0x944620b0e70e     ,0x11c592761c666    ,
            0x2214d10d014ea    ,0x415bc6d6fb7dd    ,0x7d56e76777fc5    ,0xf05dc6b27edad    ,
            0x1ccf4b44bb4820   ,0x373fc456c53bb7   ,0x69f3d1c921891c   ,0xcb2ff529eb71e4   ,
            0x185a82b87b72e95  ,0x2eb40f9f620fda6  ,0x5990681d961a1ea  ,0xabc25204e02828d  ,
            0x14962dee9dc97640 ,0x277abdcdab07d5a7 ,0x4bb5ecca963d54ab ,0x9131271922eaa606 ,
            0x116701e6ab0cd188d,0x215f77c045fbe8856,0x3ffffffffffffffff,0x7abbf6f6abb9d087f,
        };
        Since we cannot use an array of constants, we need to approximate the maximum value dynamically.
        For a precision of 32, the maximum value permitted is MAX_FIXED_EXP_32.
        For each additional precision unit, the maximum value permitted increases by approximately 1.9.
        So in order to calculate it, we need to multiply MAX_FIXED_EXP_32 by 1.9 for every additional precision unit.
        And in order to optimize for speed, we multiply MAX_FIXED_EXP_32 by 1.9^2 for every 2 additional precision units.
        Hence the general function for mapping a given precision to the maximum value permitted is:
        - precision = [32, 34, 36, ..., 62]
        - MaxFixedExp(precision) = MAX_FIXED_EXP_32 * 3.61 ^ (precision / 2 - 16)
        Since we cannot use non-integers, we do MAX_FIXED_EXP_32 * 361 ^ (precision / 2 - 16) / 100 ^ (precision / 2 - 16).
        But there is a better approximation, because this "1.9" factor in fact extends beyond a single decimal digit.
        So instead, we use 0xeb5ec5975959c565 / 0x4000000000000000, which yields maximum values quite close to real ones:
        maxExpArray = {
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            -------------------,-------------------,-------------------,-------------------,
            0x386bfdba29       ,-------------------,0xcf8014760e       ,-------------------,
            0x2fb1d8fe07b      ,-------------------,0xaf67a93bb37      ,-------------------,
            0x285145f31a8f     ,-------------------,0x944620b0e5ee     ,-------------------,
            0x2214d10d0112e    ,-------------------,0x7d56e7677738e    ,-------------------,
            0x1ccf4b44bb20d0   ,-------------------,0x69f3d1c9210d27   ,-------------------,
            0x185a82b87b5b294  ,-------------------,0x5990681d95d4371  ,-------------------,
            0x14962dee9dbd672b ,-------------------,0x4bb5ecca961fb9bf ,-------------------,
            0x116701e6ab0967080,-------------------,0x3fffffffffffe6652,-------------------,
        };
    */
    function fixedExp(uint256 _x, uint8 _precision) constant returns (uint256) {
        uint256 maxExp = MAX_FIXED_EXP_32;
        for (uint8 p = 32; p < _precision; p += 2)
            maxExp = (maxExp * 0xeb5ec5975959c565) >> (64-2);

        assert(_x <= maxExp);
        return fixedExpUnsafe(_x, _precision);
    }

    /**
        fixedExp
        Calculates e ^ x according to maclauren summation:

        e^x = 1 + x + x ^ 2 / 2!...+ x ^ n / n!

        and returns e ^ (x >> 32) << 32, that is, upshifted for accuracy

        Input range:
            - Function ok at    <= 242329958953
            - Function fails at >= 242329958954

        This method is is visible for testcases, but not meant for direct use.

        The values in this method been generated via the following python snippet:

        def calculateFactorials():
            """Method to print out the factorials for fixedExp"""

            ni = []
            ni.append(295232799039604140847618609643520000000) # 34!
            ITERATIONS = 34
            for n in range(1, ITERATIONS, 1) :
                ni.append(math.floor(ni[n - 1] / n))
            print( "\n        ".join(["xi = (xi * _x) >> _precision;\n        res += xi * %s;" % hex(int(x)) for x in ni]))

    */
    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;
    }
}


update

update

pragma solidity ^0.4.2;

contract PriceCalculator {

	function getPrice(string manufacturer, string productType, uint price) constant returns(uint) {
		return price * 5 / 100;
	}
}

contract Epam {

	struct Product {
		address retailer;
		string manufacturer;
		string productType;
		address customer;
		string warrantyId;
		uint warrantyEndDate;
		uint price;
	}

	struct Claim {
		address claimant;
		uint amount;
		string serial;
	}

	address owner;
	mapping(string => Product) products;
	mapping(uint => Claim) claims;
	uint claimCount;

	PriceCalculator calculator;

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

	modifier noWarranty(string serial) {
		if(!isWarrantyValid(serial)) {
			throw;
		}
		_;
	}

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

	function updateCalculator(address contractAddress) ownerOnly {
		calculator = PriceCalculator(contractAddress);
	}

	function requestWarranty(string serial, address customer, uint endDate, uint price) noWarranty(serial) {
		Product memory product;
		product.retailer = msg.sender;
		product.customer = customer;
		product.warrantyEndDate = endDate;
		product.price = price;

		products[serial] = product;
	}

	function claimWaranty(string serial, uint amount) {
		Claim memory claim;
		claim.claimant = msg.sender;
		claim.amount = amount;
		claim.serial = serial;
		claims[claimCount++] = claim;
	}

	function isWarrantyValid(string serial) constant returns (bool) {
		return products[serial].warrantyEndDate < now;
	}

	function getEndDate(string serial) constant returns (uint) {
		return products[serial].warrantyEndDate;
	}

	function getCustomer(string serial) constant returns (address) {
		return products[serial].customer;
	}

}

pragma solidity ^0.4.2;

contract PriceCalculator {

	function getPrice(string manufacturer, string productType, uint price) constant returns(uint) {
		return price * 5 / 100;
	}
}

contract Epam {

	struct Product {
		address retailer;
		string manufacturer;
		string productType;
		address customer;
		string warrantyId;
		uint warrantyEndDate;
		uint price;
	}

	struct Claim {
		address claimant;
		uint amount;
		string serial;
	}

	address owner;
	mapping(string => Product) products;
	mapping(uint => Claim) claims;
	uint claimCount;

	PriceCalculator calculator;

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

	modifier noWarranty(string serial) {
		if(!isWarrantyValid(serial)) {
			throw;
		}
		_;
	}

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

	function updateCalculator(address contractAddress) ownerOnly {
		calculator = PriceCalculator(contractAddress);
	}

	function requestWarranty(string serial, address customer, uint endDate, uint price) noWarranty(serial) {
		Product product;
		product.retailer = msg.sender;
		product.customer = customer;
		product.warrantyEndDate = endDate;
		product.price = price;

		products[serial] = product;
	}

	function claimWaranty(string serial, uint amount) {
		Claim claim;
		claim.claimant = msg.sender;
		claim.amount = amount;
		claim.serial = serial;
		claims[claimCount++] = claim;
	}

	function isWarrantyValid(string serial) constant returns (bool) {
		return products[serial].warrantyEndDate < now;
	}

	function getEndDate(string serial) constant returns (uint) {
		return products[serial].warrantyEndDate;
	}

	function getCustomer(string serial) constant returns (address) {
		return products[serial].customer;
	}

}


Remember last_time

Remember last_time

pragma solidity ^0.4.11;

contract Token {
	uint256 public totalSupply;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;

    /* This generates a public event on the blockchain that will notify clients */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        require(balanceOf[msg.sender] >= _value);            // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]);  // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Allow another contract to spend some tokens in your behalf */
    function approve(address _spender, uint256 _value) returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        require(balanceOf[_from] >= _value);                 // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]);  // Check for overflows
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        Transfer(_from, _to, _value);
        return true;
    }

    uint public id; /* To ensure distinct contracts for different tokens owned by the same owner */
    address public owner;
    bool public sealed = false;

    function Token(uint _id) {
        owner = msg.sender;
        id = _id;
    }

    /* Allows the owner to mint more tokens */
    function mint(address _to, uint256 _value) returns (bool) {
    	require(msg.sender == owner);						 // Only the owner is allowed to mint
    	require(!sealed);								     // Can only mint while unsealed
    	require(balanceOf[_to] + _value >= balanceOf[_to]);  // Check for overflows
    	balanceOf[_to] += _value;
    	totalSupply += _value;
    	return true;
    }

    function seal() {
    	require(msg.sender == owner);
    	sealed = true;
    }
}

contract Withdraw {
	Token public token;

	function Withdraw(Token _token) {
		token = _token;
	}

	function () payable {}

	function withdraw() {
		require(token.sealed());
		require(token.balanceOf(msg.sender) > 0);
		uint amount = token.balanceOf(msg.sender);
		if (!token.transferFrom(msg.sender, this, amount) || !msg.sender.send(amount)) {
			throw;
		}
	}
}

contract TokenGame {
	address public owner;
	uint public cap_in_wei;
	uint constant initial_duration = 7 days;
	uint constant time_extension_from_doubling = 7 days;
	uint constant time_of_half_decay = 7 days;
	Token public excess_token; /* Token contract used to receive excess after the sale */
	Withdraw excess_withdraw;  /* Withdraw contract distributing the excess */
 	Token public game_token;   /* Token contract used to receive prizes */
 	uint public end_time; 	   /* Current end time */
 	uint last_time = 0;        /* Timestamp of the latest contribution */
 	uint256 ema = 0;           /* Current value of the EMA */
 	uint total_wei_given = 0;  /* Total amount of wei given via fallback function */

	function TokenGame(uint _cap_in_wei) {
		owner = msg.sender;
		cap_in_wei = _cap_in_wei;
		excess_token = Token(1);
		excess_withdraw = Withdraw(excess_token);
		game_token = Token(2);
		end_time = now + initial_duration;
	}

	function () payable {
		require(now <= end_time);	// Check that the sale has not ended
		require(msg.value > 0);     // Check that something has been sent
		total_wei_given += msg.value;
		ema = msg.value + ema * time_of_half_decay / (time_of_half_decay + (now - last_time) );
		last_time = now;
		uint extended_time = now + ema * time_extension_from_doubling / total_wei_given;
		if (extended_time > end_time) {
			end_time = extended_time;
		}
		if (!excess_token.mint(msg.sender, msg.value) || !game_token.mint(msg.sender, msg.value)) {
			throw;
		}
	}

	function finalise() {
		require(now > end_time);
		excess_token.seal();
		game_token.seal();
		if (this.balance > cap_in_wei) {
			if (!excess_withdraw.send(this.balance - cap_in_wei) || !owner.send(cap_in_wei)) {
				throw;
			}
		} else {
			if (!owner.send(this.balance)) {
				throw;
			}
		}
	}
}

pragma solidity ^0.4.11;

contract Token {
	uint256 public totalSupply;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    mapping (address => mapping (address => uint256)) public allowance;

    /* This generates a public event on the blockchain that will notify clients */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        require(balanceOf[msg.sender] >= _value);            // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]);  // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    /* Allow another contract to spend some tokens in your behalf */
    function approve(address _spender, uint256 _value) returns (bool success) {
        allowance[msg.sender][_spender] = _value;
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        require(balanceOf[_from] >= _value);                 // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]);  // Check for overflows
        require(_value <= allowance[_from][msg.sender]);     // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        Transfer(_from, _to, _value);
        return true;
    }

    uint public id; /* To ensure distinct contracts for different tokens owned by the same owner */
    address public owner;
    bool public sealed = false;

    function Token(uint _id) {
        owner = msg.sender;
        id = _id;
    }

    /* Allows the owner to mint more tokens */
    function mint(address _to, uint256 _value) returns (bool) {
    	require(msg.sender == owner);						 // Only the owner is allowed to mint
    	require(!sealed);								     // Can only mint while unsealed
    	require(balanceOf[_to] + _value >= balanceOf[_to]);  // Check for overflows
    	balanceOf[_to] += _value;
    	totalSupply += _value;
    	return true;
    }

    function seal() {
    	require(msg.sender == owner);
    	sealed = true;
    }
}

contract Withdraw {
	Token public token;

	function Withdraw(Token _token) {
		token = _token;
	}

	function () payable {}

	function withdraw() {
		require(token.sealed());
		require(token.balanceOf(msg.sender) > 0);
		uint amount = token.balanceOf(msg.sender);
		if (!token.transferFrom(msg.sender, this, amount) || !msg.sender.send(amount)) {
			throw;
		}
	}
}

contract TokenGame {
	address public owner;
	uint public cap_in_wei;
	uint constant initial_duration = 7 days;
	uint constant time_extension_from_doubling = 7 days;
	uint constant time_of_half_decay = 7 days;
	Token public excess_token; /* Token contract used to receive excess after the sale */
	Withdraw excess_withdraw;  /* Withdraw contract distributing the excess */
 	Token public game_token;   /* Token contract used to receive prizes */
 	uint public end_time; 	   /* Current end time */
 	uint last_time = 0;        /* Timestamp of the latest contribution */
 	uint256 ema = 0;           /* Current value of the EMA */
 	uint total_wei_given = 0;  /* Total amount of wei given via fallback function */

	function TokenGame(uint _cap_in_wei) {
		owner = msg.sender;
		cap_in_wei = _cap_in_wei;
		excess_token = Token(1);
		excess_withdraw = Withdraw(excess_token);
		game_token = Token(2);
		end_time = now + initial_duration;
	}

	function () payable {
		require(now <= end_time);	// Check that the sale has not ended
		require(msg.value > 0);     // Check that something has been sent
		total_wei_given += msg.value;
		ema = msg.value + ema * time_of_half_decay / (time_of_half_decay + (now - last_time) );
		uint extended_time = now + ema * time_extension_from_doubling / total_wei_given;
		if (extended_time > end_time) {
			end_time = extended_time;
		}
		if (!excess_token.mint(msg.sender, msg.value) || !game_token.mint(msg.sender, msg.value)) {
			throw;
		}
	}

	function finalise() {
		require(now > end_time);
		excess_token.seal();
		game_token.seal();
		if (this.balance > cap_in_wei) {
			if (!excess_withdraw.send(this.balance - cap_in_wei) || !owner.send(cap_in_wei)) {
				throw;
			}
		} else {
			if (!owner.send(this.balance)) {
				throw;
			}
		}
	}
}


removed crosswithdraw.sol

removed crosswithdraw.sol

// This contract just saves in the blockchain the intention to withdraw dth
// A Bot will execute this operation in the ETC blockchain and will save
// the result back
contract Owned {
    /// Prevents methods from perfoming any value transfer
    modifier noEther() {if (msg.value > 0) throw; _}
    /// Allows only the owner to call a function
    modifier onlyOwner { if (msg.sender == owner) _ }

    function Owned() { owner = msg.sender;}
    address owner;

    function changeOwner(address _newOwner) onlyOwner {
        owner = _newOwner;
    }

    function execute(address _dst, uint _value, bytes _data) onlyOwner {
        _dst.call.value(_value)(_data);
    }

    function getOwner() noEther constant returns (address) {
        return owner;
    }
}

contract CrossWhitehatWithdraw is Owned {
    address bot;
    uint price;

    Operation[] public operations;

    modifier onlyBot { if ((msg.sender == owner)||(msg.sender == bot)) _ }

    struct Operation {
        address dth;
        address etcBeneficiary;
        uint percentageWHG;
        uint queryTime;

        uint answerTime;
        uint result;
        bytes32 etcTxHash;
    }

    function CrossWhitehatWithdraw(uint _price, address _bot) Owned() {
        price = _price;
        bot = _bot;
    }

    function withdraw(address _etcBeneficiary, uint _percentageWHG) returns (uint) {
        if (_percentageWHG > 100) throw;
        if (msg.value < price) throw;
        Operation op = operations[operations.length ++];
        op.dth = msg.sender;
        op.etcBeneficiary = _etcBeneficiary;
        op.percentageWHG = _percentageWHG;
        op.queryTime = now;
        Withdraw(op.dth, op.etcBeneficiary, op.percentageWHG, operations.length -1);

        return operations.length -1;
    }

    function setResult(uint _idOperation, uint _result, bytes32 _etcTxHash) onlyBot noEther {
        Operation op = operations[_idOperation];
        if (op.dth == 0) throw;
        op.answerTime = now;
        op.result = _result;
        op.etcTxHash = _etcTxHash;
        WithdrawResult(_idOperation, _etcTxHash, _result);
    }

    function setBot(address _bot) onlyOwner noEther  {
        bot = _bot;
    }

    function getBot() noEther constant returns (address) {
        return bot;
    }

    function setPrice(uint _price) onlyOwner noEther  {
        price = _price;
    }

    function getPrice() noEther constant returns (uint) {
        return price;
    }

    function getOperation(uint _idOperation) noEther constant returns (address dth,
        address etcBeneficiary,
        uint percentageWHG,
        uint queryTime,
        uint answerTime,
        uint result,
        bytes32 dthTxHash)
    {
        Operation op = operations[_idOperation];
        return (op.dth,
                op.etcBeneficiary,
                op.percentageWHG,
                op.queryTime,
                op.answerTime,
                op.result,
                op.etcTxHash);
    }

    function getOperationsNumber() noEther constant returns (uint) {
        return operations.length;
    }

    function() {
        throw;
    }

    function kill() onlyOwner {
        selfdestruct(owner);
    }

    event Withdraw(address indexed dth, address indexed beneficiary, uint percentageWHG, uint proposal);
    event WithdrawResult(uint indexed proposal, bytes32 indexed etcTxHash, uint result);

}


Check if it is safe to add two numbers

Check if it is safe to add two numbers

pragma solidity ^0.4.11;

contract Safe {

    // Check if it is safe to add two numbers

    function safeAdd(uint a, uint b) internal returns (uint) {

        uint c = a + b;

        assert(c >= a && c >= b);

        return c;

    }

    // Check if it is safe to subtract two numbers

    function safeSubtract(uint a, uint b) internal returns (uint) {

        uint c = a - b;

        assert(b <= a && c <= a);

        return c;

    }

    function safeMultiply(uint a, uint b) internal returns (uint) {

        uint c = a * b;

        assert(a == 0 || (c / a) == b);

        return c;

    }

    function shrink128(uint a) internal returns (uint128) {

        assert(a < 0x100000000000000000000000000000000);

        return uint128(a);

    }

    // mitigate short address attack

    modifier onlyPayloadSize(uint numWords) {

        assert(msg.data.length == numWords * 32 + 4);

        _;

    }

    // allow ether to be received

    function () payable { }

}

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


Some minor formatting

Some minor formatting

contract IPOI {

  struct Idea {
    uint32 id;
    address owner;
    address[] parties;
    uint256 date;
    string description;
    bytes proofDoc;
  }

  //Declares a state variable 'numIdeaId'
  uint32 numIdeaId;
  //Creates a mapping of Idea datatypes
  mapping(uint => Idea) ideas;

  mapping(address => uint32[]) ownerIdeas;

  // Owner
  address public owner;

  // Fee to use the service
  uint public fee;

  //Set owner and fee
  function IPOI(uint feeParam) {
    owner = msg.sender;
    fee = feeParam;
  }

  function changeContractFee(uint newFee) onlyowner {
    fee = newFee;
  }

  // Create initial idea contract
  function createIdea(address ideaOwner, address[] partiesEntry, string descriptionEntry) onlyowner returns(uint32 ideaId) {

    if (msg.value >= fee) {

      if (msg.value > fee) {
        msg.sender.send(msg.value - fee); //payed more than required => refund
      }

      ideaId = numIdeaId++;
      Idea idea = ideas[ideaId];
      ownerIdeas[ideaOwner].push(ideaId);
      idea.id = ideaId;
      idea.owner = ideaOwner;

      for (uint i = 0; i < partiesEntry.length; i++) {
        idea.parties.push(partiesEntry[i]);
      }

      idea.date = now;
      idea.description = descriptionEntry;

      IdeaChangeEvent(idea.date, "IPOI Contract Creation", bytes(descriptionEntry));
    }
  }

  function getIdea(address ideaOwner) returns(uint32[]) {
    return ownerIdeas[ideaOwner];
  }

  function getIdeaDate(uint ideaId) returns(uint ideaDate) {
    return ideas[ideaId].date;
  }

  function getIdeaDescription(uint ideaId) returns(string ideaDescription) {
    return ideas[ideaId].description;
  }

  function getIdeaParties(uint ideaId) returns(address[] ideaParties) {
    return ideas[ideaId].parties;
  }

  function getOwner() returns(address owner) {
    return owner;
  }

  // Upload documentation for proof of idea (signed signatures?)
  function ideaProofDocument(bytes IPOIProofHash, uint ideaId) onlyowner {
    ideas[ideaId].proofDoc = IPOIProofHash;
    IdeaChangeEvent(block.timestamp, "Entered Idea Proof Document", "Idea proof in IPFS");
  }

  // Declare event structure
  event IdeaChangeEvent(uint256 date, bytes indexed name, bytes indexed description);

  function destroy() {
    if (msg.sender == owner) {
      suicide(owner); // send any funds to owner
    }
  }

  modifier onlyowner() {
    if (msg.sender == owner)
      _
  }

  // This function gets executed if a transaction with invalid data is sent to
  // the contract or just ether without data. We revert the send so that no-one
  // accidentally loses money when using the contract.
  function() {
    throw;
  }
}


investmentAsset

investmentAsset

pragma solidity ^0.4.21;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/InvestmentAsset.sol";
import "./helpers/ThrowProxy.sol";

contract TestInvestmentAsset {

}

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