Make overide of ERC721.isApprovedForAll affect the ERC721 logic (#2597)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "./extensions/IERC721Enumerable.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping (uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping (address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC721).interfaceId
            || interfaceId == type(IERC721Metadata).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0
            ? string(abi.encodePacked(baseURI, tokenId.toString()))
            : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

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

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "./extensions/IERC721Enumerable.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping (uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping (address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC721).interfaceId
            || interfaceId == type(IERC721Metadata).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0
            ? string(abi.encodePacked(baseURI, tokenId.toString()))
            : '';
    }

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

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

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}


token contract

token contract

contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract owned{
  address public owner;
  function owned(){
    owner = msg.sender;
  }
  modifier onlyOwner{
    if(msg.sender != owner) throw;
    _
  }
  function transferOwnership(address newOwner) onlyOwner{
    owner = newOwner;
  }
}
contract MyToken is owned{
    /* Public variables of the token */
    string public standard = 'Token 0.1';
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    /* Simple array of tokenholders */
    address[] tokenHolders;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    /* Indexes for people's addresses*/
    mapping (uint => address) public indexes;
    uint public currentIndex;
    mapping (addres => uint) public etherBalanceOf;
    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);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function MyToken(
        uint256 initialSupply,
        string tokenName,
        uint8 decimalUnits,
        string tokenSymbol,
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
        totalSupply = initialSupply;                        // Update total supply
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
        decimals = decimalUnits;                            // Amount of decimals for display purposes
        msg.sender.send(msg.value);                         // Send back any ether sent accidentally
        currentIndex = 0;
        indexes[currentIndex] = msg.sender;                 // Hashes an index to an address.
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        currentIndex++;                                      // increments the currentIndex by 1
        indexes[currentIndex] = _to;                         // keeps a hash to the address by index.
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    //Don't need this anymore if I use a hash with indexes as keys and values as addresses
    /* Fix tokenholder array */
    /*function checkTokenHolders() returns(bool success){
      address[] newTokenHolders
      for(var i = 0; i < tokenHolders.length; i++){
        if(balanceOf[tokenHolders[i]] > 0){
          newTokenHolders.push(tokenHolders[i])
        }
      }
      delete tokenHolders;
      for(var i = 0; i < newTokenHolders.length; i++){
        tokenHolders.push(newTokenHolders[i]);
      }
      delete newTokenHolders;
      return true;
    }*/

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

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;  // Check for overflows
        if (_value > allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        //tokenHolders.push(_to);                             // Adds the address coin is being sent to in to the array
        //checkTokenHolders()                                 // Makes sure there aren't empty addresses in the array
        currentIndex ++;
        indexes[currentIndex] = _to;
        Transfer(_from, _to, _value);
        return true;
    }

    /* Transfer funds based on number of coins. This will later be moved in to the unnamed function */
    function transferFunds() returns(bool success){
        if(etherBalanceOf(msg.sender)>0){
          msg.sender.send(etherBalanceOf(msg.sender));
          return true;
        }
        return false;
    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {
        for(var i = 0; i < currentIndex + 1; i++){
          etherBalanceOf[indexes[i]] += balanceOf[indexes[i]]/totalSupply*msg.value
        }
    }
}

contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract owned{
  address public owner;
  function owned(){
    owner = msg.sender;
  }
  modifier onlyOwner{
    if(msg.sender != owner) throw;
    _
  }
  function transferOwnership(address newOwner) onlyOwner{
    owner = newOwner;
  }
}
contract MyToken is owned{
    /* Public variables of the token */
    string public standard = 'Token 0.1';
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    /* Simple array of tokenholders */
    address[] tokenHolders;

    /* This creates an array with all balances */
    mapping (address => uint256) public balanceOf;
    /* Indexes for people's addresses*/
    mapping (uint => address) public indexes;
    uint public currentIndex;
    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);

    /* Initializes contract with initial supply tokens to the creator of the contract */
    function MyToken(
        uint256 initialSupply,
        string tokenName,
        uint8 decimalUnits,
        string tokenSymbol,
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
        totalSupply = initialSupply;                        // Update total supply
        name = tokenName;                                   // Set the name for display purposes
        symbol = tokenSymbol;                               // Set the symbol for display purposes
        decimals = decimalUnits;                            // Amount of decimals for display purposes
        msg.sender.send(msg.value);                         // Send back any ether sent accidentally
        currentIndex = 0;
        indexes[currentIndex] = msg.sender;                 // Hashes an index to an address.
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        currentIndex++;                                      // increments the currentIndex by 1
        indexes[currentIndex] = _to;                         // keeps a hash to the address by index.
        Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place
    }

    //Don't need this anymore if I use a hash with indexes as keys and values as addresses
    /* Fix tokenholder array */
    /*function checkTokenHolders() returns(bool success){
      address[] newTokenHolders
      for(var i = 0; i < tokenHolders.length; i++){
        if(balanceOf[tokenHolders[i]] > 0){
          newTokenHolders.push(tokenHolders[i])
        }
      }
      delete tokenHolders;
      for(var i = 0; i < newTokenHolders.length; i++){
        tokenHolders.push(newTokenHolders[i]);
      }
      delete newTokenHolders;
      return true;
    }*/

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

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balanceOf[_from] < _value) throw;                 // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw;  // Check for overflows
        if (_value > allowance[_from][msg.sender]) throw;   // Check allowance
        balanceOf[_from] -= _value;                          // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
        allowance[_from][msg.sender] -= _value;
        //tokenHolders.push(_to);                             // Adds the address coin is being sent to in to the array
        //checkTokenHolders()                                 // Makes sure there aren't empty addresses in the array
        currentIndex ++;
        indexes[currentIndex] = _to;
        Transfer(_from, _to, _value);
        return true;
    }

    /* Transfer funds based on number of coins. This will later be moved in to the unnamed function */
    function transferFunds() returns(bool success){

    }

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {

    }
}


update dragonstone contract

update dragonstone contract

pragma solidity ^0.4.25;

contract DragonStone {

    address public creator;
    mapping (address => uint) public balances;

    event Transfered(address from, address to, uint amount);

    constructor() public {
        creator = msg.sender;
    }

    function create(address receiver, uint amount) public {
        require(msg.sender == creator);
        balances[receiver] += amount;
    }

    function transfer(address receiver, uint amount) public {
        require(balances[msg.sender] > amount);
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Transfered(msg.sender, receiver, amount);
    }
}

pragma solidity ^0.4.24;

/*
Currency that can only be issued by its creator and transferred to anyone
*/
contract DragonStone {
    address public creator;
    mapping (address => uint) public balances;

    // event that notifies when a transfer has completed
    event Delivered(address from, address to, uint amount);

    constructor() public {
        creator = msg.sender;
    }

    function create(address receiver, uint amount) public {
        if (msg.sender != creator) return;
        balances[receiver] += amount;
    }

    function transfer(address receiver, uint amount) public {
        if (balances[msg.sender] < amount) return;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Delivered(msg.sender, receiver, amount);
    }
}


Make sendToTarget an internal function

Make sendToTarget an internal function

pragma solidity ^0.4.11;

contract cocoon {
    // Nested mapping: funds[initiator][intermediary][receiver] contains the value of ETH locked up by that triple.
    mapping (address => mapping (address => mapping (address => uint))) funds;

    // The account from where ETH is received is the initiator.
    function storeInContract(address intermediary, address receiver) payable {
        funds[msg.sender][intermediary][receiver] += msg.value;
    }

    // Get amount of ETH locked up with a triple.
    function getValue(address initiator, address intermediary, address receiver) constant returns (uint) {
        return funds[initiator][intermediary][receiver];
    }

    // Common function used to check is sufficient balance is present in a trio and send it to the target if that is the case.
    function sendToTarget(address initiator, address intermediary, address receiver, address target, uint amount) internal {
        if (funds[initiator][intermediary][receiver] >= amount) {
            funds[initiator][intermediary][receiver] -= amount;
            target.transfer(amount);
        }
        else {
            throw;
        }
    }

    // Send ETH to the receiver from the initiator.
    function sendToReceiver(address intermediary, address receiver, uint amount) {
        sendToTarget(msg.sender, intermediary, receiver, receiver, amount);
    }

    // Send ETH to the receiver from the intermediary.
    function moveToReceiver(address initiator, address receiver, uint amount) {
        sendToTarget(initiator, msg.sender, receiver, receiver, amount);
    }

    // Send ETH to the initiator from the intermediary.
    function moveToInitiator(address initiator, address receiver, uint amount) {
        sendToTarget(initiator, msg.sender, receiver, initiator, amount);
    }
}

pragma solidity ^0.4.11;

contract cocoon {
    // Nested mapping: funds[initiator][intermediary][receiver] contains the value of ETH locked up by that triple.
    mapping (address => mapping (address => mapping (address => uint))) funds;

    // The account from where ETH is received is the initiator.
    function storeInContract(address intermediary, address receiver) payable {
        funds[msg.sender][intermediary][receiver] += msg.value;
    }

    // Get amount of ETH locked up with a triple.
    function getValue(address initiator, address intermediary, address receiver) constant returns (uint) {
        return funds[initiator][intermediary][receiver];
    }

    // Common function used to check is sufficient balance is present in a trio and send it to the target if that is the case.
    function sendToTarget(address initiator, address intermediary, address receiver, address target, uint amount) {
        if (funds[initiator][intermediary][receiver] >= amount) {
            funds[initiator][intermediary][receiver] -= amount;
            target.transfer(amount);
        }
        else {
            throw;
        }
    }

    // Send ETH to the receiver from the initiator.
    function sendToReceiver(address intermediary, address receiver, uint amount) {
        sendToTarget(msg.sender, intermediary, receiver, receiver, amount);
    }

    // Send ETH to the receiver from the intermediary.
    function moveToReceiver(address initiator, address receiver, uint amount) {
        sendToTarget(initiator, msg.sender, receiver, receiver, amount);
    }

    // Send ETH to the initiator from the intermediary.
    function moveToInitiator(address initiator, address receiver, uint amount) {
        sendToTarget(initiator, msg.sender, receiver, initiator, amount);
    }
}


fixed token.sol merge conflicts

fixed token.sol merge conflicts

pragma solidity ^0.4.15;

import './interfaces/ERC20Interface.sol';
import './utils/SafeMath.sol';

/**
 * @title Token
 * @dev Contract that implements ERC20 token standard
 * Is deployed by `Crowdsale.sol`, keeps track of balances, etc.
 */

 contract Token is ERC20Interface {

 	Queue public queue;

 	string public constant name = "BAB";
    string public constant symbol = "BAB";
    uint8 public constant decimals = 18;  // 18 is the most common number of decimal places
   	address owner;

   	uint256 public totalSupply;

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

   	using SafeMath for uint256;

   	modifier isVerifiedBuyer() {
     		require(buyer != owner);
       	_;
     }

   	function Token(uint256 _totalSupply, address buyerAddress) public {
       	balances[buyerAddress] = _totalSupply;
     	totalSupply = _totalSupply;
     	// queue.enqueue(buyerAddress);
     }

   	function addSupply(address buyerAddress, uint256 _amount) isVerifiedBuyer() public {
       	totalSupply += _amount;
       	balances[buyerAddress] = balances[buyerAddress].add(_amount);
     }

     function burnToken(uint256 _amount) isOwner() public {
       if (balances[msg.sender] >= _amount) {
         totalSupply -= _amount;
         balances[msg.sender] = balances[msg.sender].sub(_amount);
       }
     }

 		/* @param _owner The address from which the balance will be retrieved
       @return The balance */
     function balanceOf(address _owner) constant public returns (uint256 balance) {
     		return balances[_owner];
     }

   	/* @notice send `_value` token to `_to` from `msg.sender`
       @param _to The address of the recipient
       @param _value The amount of token to be transferred
       @return Whether the transfer was successful or not */
     function transfer(address _to, uint256 _value) public returns (bool success) {
       	if (balances[msg.sender] < _value) {
         		return false;
         }
         balances[msg.sender] = balances[msg.sender].sub(_value);
       	balances[_to] = balances[_to].add(_value);
       	Transfer(msg.sender, _to, _value);
       	return true;
     }

   	  /* @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
         @param _from The address of the sender
         @param _to The address of the recipient
         @param _value The amount of token to be transferred
         @return Whether the transfer was successful or not */
     function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
       	uint256 allowed = approved[_from][msg.sender];

       	if (balances[_from] < _value || allowed < _value) {
           	return false;
         }
       	balances[_from] = balances[_from].sub(_value);
       	approved[_from][msg.sender] = allowed.sub(_value);
  				balances[_to] = balances[_to].add(_value);
       	Transfer(_from, _to, _value);
       	return true;
     }

     /*@notice `msg.sender` approves `_spender` to spend `_value` tokens
       @param _spender The address of the account able to transfer the tokens
       @param _value The amount of tokens to be approved for transfer
       @return Whether the approval was successful or not */
     function approve(address _spender, uint256 _value) public returns (bool success) {
       	approved[msg.sender][_spender] = _value;
       	Approval(msg.sender, _spender, _value);
       	return true;
     }

   	function refundApprove(address _refundee, uint256 _value) isOwner() public returns (bool success) {
       	approved[_refundee][msg.sender] = _value;
       	Approval(_refundee, msg.sender, _value);
       	return true;
     }

    /*@param _owner The address of the account owning tokens
      @param _spender The address of the account able to transfer the tokens
      @return Amount of remaining tokens allowed to spent */
     function allowance(address _owner, address _spender) constant public returns (uint256 remaining) {
       	return approved[_owner][_spender];
     }

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

pragma solidity ^0.4.15;

import './interfaces/ERC20Interface.sol';
import './utils/SafeMath.sol';
import './Queue.sol';

/**
 * @title Token
 * @dev Contract that implements ERC20 token standard
 * Is deployed by `Crowdsale.sol`, keeps track of balances, etc.
 */

 contract Token is ERC20Interface {

 	Queue public queue;

 	string public constant name = "BAB";
    string public constant symbol = "BAB";
    uint8 public constant decimals = 18;  // 18 is the most common number of decimal places

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

   	using SafeMath for uint256;

   	modifier isVerifiedBuyer() {
     		require(buyer != owner);
       	_;
     }

   	function Token(uint256 _totalSupply, address buyerAddress) public {
       	balances[buyerAddress] = _totalSupply;
     	totalSupply = _totalSupply;
     	// queue.enqueue(buyerAddress);
     }

   	function addSupply(address buyerAddress, uint256 _amount) isVerifiedBuyer() public {
       	totalSupply += _amount;
       	balances[buyerAddress] = balances[buyerAddress].add(_amount);
     }

     function burnToken(uint256 _amount) isOwner() public {
       if (balances[msg.sender] >= _amount) {
         totalSupply -= _amount;
         balances[msg.sender] = balances[msg.sender].sub(_amount);
       }
     }

 		/* @param _owner The address from which the balance will be retrieved
       @return The balance */
     function balanceOf(address _owner) constant public returns (uint256 balance) {
     		return balances[_owner];
     }

   	/* @notice send `_value` token to `_to` from `msg.sender`
       @param _to The address of the recipient
       @param _value The amount of token to be transferred
       @return Whether the transfer was successful or not */
     function transfer(address _to, uint256 _value) public returns (bool success) {
       	if (balances[msg.sender] < _value) {
         		return false;
         }
         balances[msg.sender] = balances[msg.sender].sub(_value);
       	balances[_to] = balances[_to].add(_value);
       	Transfer(msg.sender, _to, _value);
       	return true;
     }

   	  /* @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
         @param _from The address of the sender
         @param _to The address of the recipient
         @param _value The amount of token to be transferred
         @return Whether the transfer was successful or not */
     function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
       	uint256 allowed = approved[_from][msg.sender];

       	if (balances[_from] < _value || allowed < _value) {
           	return false;
         }
       	balances[_from] = balances[_from].sub(_value);
       	approved[_from][msg.sender] = allowed.sub(_value);
  				balances[_to] = balances[_to].add(_value);
       	Transfer(_from, _to, _value);
       	return true;
     }

     /*@notice `msg.sender` approves `_spender` to spend `_value` tokens
       @param _spender The address of the account able to transfer the tokens
       @param _value The amount of tokens to be approved for transfer
       @return Whether the approval was successful or not */
     function approve(address _spender, uint256 _value) public returns (bool success) {
       	approved[msg.sender][_spender] = _value;
       	Approval(msg.sender, _spender, _value);
       	return true;
     }

   	function refundApprove(address _refundee, uint256 _value) isOwner() public returns (bool success) {
       	approved[_refundee][msg.sender] = _value;
       	Approval(_refundee, msg.sender, _value);
       	return true;
     }

    /*@param _owner The address of the account owning tokens
      @param _spender The address of the account able to transfer the tokens
      @return Amount of remaining tokens allowed to spent */
     function allowance(address _owner, address _spender) constant public returns (uint256 remaining) {
       	return approved[_owner][_spender];
     }

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


FedCoup contract updated

FedCoup contract updated

pragma solidity ^0.4.4;
import "./FCCPrice.sol";
import "./FCCPriceDefault.sol";
import "zeppelin/token/MintableToken.sol";

/*
* Contract for Federation Coupon System.
*/
contract FedCoup is MintableToken {

    using SafeMath for uint;

    /*
    * Name of the Federation Coupon System.
    */
    string public name = "FedCoup";

    /*
    * FedCoup currency symbol.
    */
    string public symbol = "FCC";

    uint public decimals = 18;

    /* default FCC (fedcoup currency) value as 0.01 USD.
     * This default value will be used until FCC price ticker available in the exchanges.
     * If price ticker available, in the next version, the method will be included to pull price data from available exchanges and average of them will be assigned to this variable.
     */
    uint256 FCC_value = 10 finney;

    /*
    * constant S,B coupon (federation coupon) price as 0.01 USD.
    */
    uint256 constant constant_coupon_price = 10 finney;

    /*
    * residual B coupons which accumulated over the period due to B coupon transfers.
    */
    uint residualBcoupons = 0;

    /*
    * residual S coupons which accumulated over the period due to B coupon transfers.
    */
    uint residualScoupons = 0;

    /*
    * balance of S coupons for each address
    */
    mapping (address => uint) balance_S_coupons;

    /*
    * balance of B coupons for each address
    */
    mapping (address => uint) balance_B_coupons;

    /*
    * Function to get FCC price.
    * While FedCoup contract deployment, this function delegated to FCCPriceDefault contract.
    * In future, this function will be delegated to new contract which would determine the FCC price from the exchange data.
    */
    FCCPrice _fCCPriceFunction;

    /*
    * Cost of B coupon (in percentage) when transfer to other user.
    * This cost necessary, otherwise B coupon will go on circulation loop and it might go on in own curreny mode.
    * Using this cost, B coupon crunched back to the system if transfer happens continuously without accepting coupons.
    */
    uint TransferCostBcoupon = 1;

    /*
    * Cost of S coupon (in percentage) when transfer to other user.
    * This cost necessary to motivate users to sell products (with coupons) instead of transfering S coupons.
    * Using this cost, S coupon crunched back to the system if transfer happens continuously without accepting coupons.
    */
    uint TransferCostScoupon = 1;

    /*
    * event to log coupon creation.
    */
    event CouponsCreated(address indexed owner, uint Bcoupons, uint Scoupons);

    /*
    * event to log accepted B coupons.
    */
    event Accept_B_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log accepted S coupons.
    */
    event Accept_S_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log B coupons transfer.
    */
    event Transfer_B_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log B coupons transfer.
    */
    event Transfer_S_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log residual B coupons transfer.
    */
    event TransferResidual_B_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log residual S coupons transfer.
    */
    event TransferResidual_S_coupons(address indexed from, address indexed to, uint value);

    /*
    * FedCoup Constructor.
    */
    function FedCoup() {
        _fCCPriceFunction = FCCPriceDefault(10 finney);
    }

    /*
    * Create tokens for given FCC.
    *         _FCC : given FedCoup curreny (1FCC equal to 1 ether with respect to number format)
    */
    function createCoupons(uint _FCC) onlyPayloadSize(2 * 32) {

        /* subtract given FCC from sender FCC balance */
        balances[msg.sender] = balances[msg.sender].sub( _FCC );

        /*
        *  B coupon creation for given _FCC
        *
        *  Formula: number of B coupons =
        *
        *           (given FCC * FCC price)
        *          --------------------------
        *            constant_coupon_price
        */
        uint  newBcoupons = _FCC.mul( _fCCPriceFunction.getFCCPrice() ).div( constant_coupon_price );

        /*
        *  S coupon creation for given _FCC
        *
        *  Formula: number of S coupons =
        *
        *          (given FCC * FCC price)
        *        ---------------------------
        *          constant_coupon_price
        */
        uint  newScoupons = _FCC.mul( _fCCPriceFunction.getFCCPrice() ).div( constant_coupon_price );

        /*
        * add new coupons with existing coupon balance
        */
        balance_B_coupons[msg.sender] = balance_B_coupons[msg.sender].add( newBcoupons );
        balance_S_coupons[msg.sender] = balance_S_coupons[msg.sender].add( newScoupons );

        /* log event */
        CouponsCreated(msg.sender, newBcoupons, newScoupons);
    }

    /*
    * accept B coupons.
    *      _from : address of the coupon giver.
    *      _numberOfBcoupons : number of B coupons (1B coupon equal to 1 ether with respect to format)
    */
    function accept_B_coupons(address _from, uint _numberOfBcoupons) onlyPayloadSize(2 * 32) {

        /*
        * substract B coupons from the giver account.
        */
        balance_B_coupons[_from] = balance_B_coupons[_from].sub( _numberOfBcoupons );

        /*
        * substract equivalent S coupons from message sender(coupon acceptor) account.
        */
        balance_S_coupons[msg.sender] = balance_S_coupons[msg.sender].sub( _numberOfBcoupons );

        /*
        * convert accepted B coupons into FCC equivalent and add it to sender balance.
        *
        *  Formula: FCC =
        *
        *           (_numberOfBcoupons * constant_coupon_price)
        *          ---------------------------------------------
        *                           FCC price
        *
        */
        balances[msg.sender] = balances[msg.sender].add( _numberOfBcoupons );

        /*
        * log event.
        */
        Accept_B_coupons(_from, msg.sender, _numberOfBcoupons);
    }

    /*
    * Transfer B coupons.
    *       _to: To address where B coupons has to be send
    *       _numberOfBcoupons: number of B coupons (1 coupon equal to 1 ether)
    */
    function transferBcoupons(address _to, uint _numberOfBcoupons) onlyPayloadSize(2 * 32) {

        /*
        * substract _numberOfBcoupons from sender account.
        */
        balance_B_coupons[msg.sender] = balance_B_coupons[msg.sender].sub(_numberOfBcoupons);

        /*
        * calculate transfer cost.
        * Formula:
        *            transferCost = (1/100) * _numberOfBcoupons
        */
        uint transferCost =  _numberOfBcoupons.div( 100 ).mul(TransferCostBcoupon);

        /*
        * add transfer cost to residual B coupons.
        */
        residualBcoupons = residualBcoupons.add(transferCost);

        /*
        * subtract transfer cost from given _numberOfBcoupons and add it to the TO account.
        */
        balance_B_coupons[_to] = balance_B_coupons[_to].add( _numberOfBcoupons.sub(transferCost) );

        /*
        * log event
        */
        Transfer_B_coupons(msg.sender, _to, _numberOfBcoupons);
    }

    /*
    * Transfer S coupons.
    */
    function transferScoupons(address _to, uint _numberOfScoupons) onlyPayloadSize(2 * 32) {

        /*
        * substract _numberOfScoupons from sender account.
        */
        balance_S_coupons[msg.sender] = balance_S_coupons[msg.sender].sub(_numberOfScoupons);

        /*
        * calculate transfer cost.
        * Formula:
        *            transferCost = (1/100) * _numberOfScoupons
        */
        uint transferCost =  _numberOfScoupons.div( 100 ).mul(TransferCostScoupon);

        /*
        * add transfer cost to residual S coupons.
        */
        residualScoupons = residualScoupons.add(transferCost);

        /*
        * subtract transfer cost from given _numberOfBcoupons and add it to the TO account.
        */
        balance_S_coupons[_to] = balance_S_coupons[_to].add(_numberOfScoupons.sub(transferCost));

        /*
        * log event.
        */
        Transfer_S_coupons(msg.sender, _to, _numberOfScoupons);
    }

    /*
    * Transfer residual B coupons to entities which integrates FedCoup.
    * It's investment on entities to integrate FedCoup on their sales lifecycle.
    */
    function transferResidualBcoupons(address _to, uint _numberOfBcoupons) onlyPayloadSize(2 * 32) onlyOwner {
        residualBcoupons = residualBcoupons.sub(_numberOfBcoupons);
        balance_B_coupons[_to] = balance_B_coupons[_to].add(_numberOfBcoupons);
        /* log event */
        TransferResidual_B_coupons(msg.sender, _to, _numberOfBcoupons);
    }

    /*
    * Transfer residual B coupons to entities which integrates FedCoup.
    * It's investment on entities to integrate FedCoup on their sales lifecycle.
    */
    function transferResidualScoupons(address _to, uint _numberOfScoupons) onlyPayloadSize(2 * 32) onlyOwner {
        residualScoupons = residualScoupons.sub(_numberOfScoupons);
        balance_S_coupons[_to] = balance_S_coupons[_to].add(_numberOfScoupons);
        /* log event */
        TransferResidual_B_coupons(msg.sender, _to, _numberOfScoupons);
    }

    /*
    * Get balance of S coupons.
    */
    function balanceOf_S_coupons(address _owner) constant returns (uint Sbalance) {
        return balance_S_coupons[_owner];
    }

    /*
    * Get balance of B coupons.
    */
    function balanceOf_B_coupons(address _owner) constant returns (uint Bbalance) {
        return balance_B_coupons[_owner];
    }

    /*
    * Get balance of residual B coupons.
    */
    function getBalanceOfResidualBcoupons() constant returns(uint residualBcoupons) {
        return residualBcoupons;
    }

    /*
    * Set FCC price function to get FCC price.
    */
    function setFCCPriceFunction(address addrFCCPriceFunc) onlyPayloadSize(2 * 32) onlyOwner {
        _fCCPriceFunction = FCCPrice(addrFCCPriceFunc);
    }

    /*
    *
    */

}

pragma solidity ^0.4.4;
import "./FCCPrice.sol";
import "./FCCPriceDefault.sol";
import "zeppelin/token/MintableToken.sol";

/*
* Contract for Federation Coupon System.
*/
contract FedCoup is MintableToken {

    using SafeMath for uint;

    /*
    * Name of the Federation Coupon System.
    */
    string public name = "FedCoup";

    /*
    * FedCoup currency symbol.
    */
    string public symbol = "FCC";

    uint public decimals = 18;

    /* default FCC (fedcoup currency) value as 0.01 USD.
     * This default value will be used until FCC price ticker available in the exchanges.
     * If price ticker available, in the next version, the method will be included to pull price data from available exchanges and average of them will be assigned to this variable.
     */
    uint256 FCC_value = 10 finney;

    /*
    * constant S,B coupon (federation coupon) price as 0.01 USD.
    */
    uint256 constant constant_coupon_price = 10 finney;

    /*
    * residual B coupons which accumulated over the period due to B coupon transfers.
    */
    uint residualBcoupons = 0;

    /*
    * residual S coupons which accumulated over the period due to B coupon transfers.
    */
    uint residualScoupons = 0;

    /*
    * balance of S coupons for each address
    */
    mapping (address => uint) balance_S_coupons;

    /*
    * balance of B coupons for each address
    */
    mapping (address => uint) balance_B_coupons;

    /*
    * Function to get FCC price.
    * While FedCoup contract deployment, this function delegated to FCCPriceDefault contract.
    * In future, this function will be delegated to new contract which would determine the FCC price from the exchange data.
    */
    FCCPrice _fCCPriceFunction;

    /*
    * Cost of B coupon (in percentage) when transfer to other user.
    * This cost necessary, otherwise B coupon will go on circulation loop and it might go on in own curreny mode.
    * Using this cost, B coupon crunched back to the system if transfer happens continuously without accepting coupons.
    */
    uint TransferCostBcoupon = 1;

    /*
    * Cost of S coupon (in percentage) when transfer to other user.
    * This cost necessary to motivate users to sell products (with coupons) instead of transfering S coupons.
    * Using this cost, S coupon crunched back to the system if transfer happens continuously without accepting coupons.
    */
    uint TransferCostScoupon = 1;

    /*
    * event to log coupon creation.
    */
    event CouponsCreated(address indexed owner, uint Bcoupons, uint Scoupons);

    /*
    * event to log accepted B coupons.
    */
    event Accept_B_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log accepted S coupons.
    */
    event Accept_S_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log B coupons transfer.
    */
    event Transfer_B_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log B coupons transfer.
    */
    event Transfer_S_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log residual B coupons transfer.
    */
    event TransferResidual_B_coupons(address indexed from, address indexed to, uint value);

    /*
    * event to log residual S coupons transfer.
    */
    event TransferResidual_S_coupons(address indexed from, address indexed to, uint value);

    /*
    * FedCoup Constructor.
    */
    function FedCoup() {
        _fCCPriceFunction = FCCPriceDefault(10 finney);
    }

    /*
    * Create tokens for given FCC.
    *         _FCC : given FedCoup curreny (1FCC equal to 1 ether with respect to number format)
    */
    function createCoupons(uint _FCC) onlyPayloadSize(2 * 32) {

        /* subtract given FCC from sender FCC balance */
        balances[msg.sender] = balances[msg.sender].sub( _FCC );

        /*
        *  B coupon creation for given _FCC
        *
        *  Formula: number of B coupons =
        *
        *           (given FCC * FCC price)
        *          --------------------------
        *            constant_coupon_price
        */
        uint  newBcoupons = _FCC.mul( _fCCPriceFunction.getFCCPrice() ).div( constant_coupon_price );

        /*
        *  S coupon creation for given _FCC
        *
        *  Formula: number of S coupons =
        *
        *          (given FCC * FCC price)
        *        ---------------------------
        *          constant_coupon_price
        */
        uint  newScoupons = _FCC.mul( _fCCPriceFunction.getFCCPrice() ).div( constant_coupon_price );

        /*
        * add new coupons with existing coupon balance
        */
        balance_B_coupons[msg.sender] = balance_B_coupons[msg.sender].add( newBcoupons );
        balance_S_coupons[msg.sender] = balance_S_coupons[msg.sender].add( newScoupons );

        /* log event */
        CouponsCreated(msg.sender, newBcoupons, newScoupons);
    }

    /*
    * accept B coupons.
    */
    function accept_B_coupons(address _from, uint _Bcoupons) onlyPayloadSize(2 * 32) {

        /* substract B coupons from the beneficiary account */
        balance_B_coupons[_from] = balance_B_coupons[_from].sub( _Bcoupons );

        /* substract equivalent S coupons from message sender(coupon acceptor) account */
        balance_S_coupons[msg.sender] = balance_S_coupons[msg.sender].sub( _Bcoupons );

        /* convert accepted B coupons into FCC equivalent and add it to sender balance */
        balances[msg.sender] = balances[msg.sender].add( _Bcoupons );

        /* log event */
        Accept_B_coupons(_from, msg.sender, _Bcoupons);
    }

    /*
    * Transfer B coupons.
    *       _to: To address where B coupons has to be send
    *       _numberOfBcoupons: number of B coupons (1 coupon equal to 1 ether)
    */
    function transferBcoupons(address _to, uint _numberOfBcoupons) onlyPayloadSize(2 * 32) {

        /*
        * substract _numberOfBcoupons from sender account.
        */
        balance_B_coupons[msg.sender] = balance_B_coupons[msg.sender].sub(_numberOfBcoupons);

        /*
        * calculate transfer cost.
        * Formula:
        *            transferCost = (1/100) * _numberOfBcoupons
        */
        uint transferCost =  _numberOfBcoupons.div( 100 ).mul(TransferCostBcoupon);

        /*
        * add transfer cost to residual B coupons.
        */
        residualBcoupons = residualBcoupons.add(transferCost);

        /*
        * subtract transfer cost from given _numberOfBcoupons and add it to the TO account.
        */
        balance_B_coupons[_to] = balance_B_coupons[_to].add( _numberOfBcoupons.sub(transferCost) );

        /*
        * log event
        */
        Transfer_B_coupons(msg.sender, _to, _numberOfBcoupons);
    }

    /*
    * Transfer S coupons.
    */
    function transferScoupons(address _to, uint _numberOfScoupons) onlyPayloadSize(2 * 32) {

        /*
        * substract _numberOfScoupons from sender account.
        */
        balance_S_coupons[msg.sender] = balance_S_coupons[msg.sender].sub(_numberOfScoupons);

        /*
        * calculate transfer cost.
        * Formula:
        *            transferCost = (1/100) * _numberOfScoupons
        */
        uint transferCost =  _numberOfScoupons.div( 100 ).mul(TransferCostScoupon);

        /*
        * add transfer cost to residual S coupons.
        */
        residualScoupons = residualScoupons.add(transferCost);

        /*
        * subtract transfer cost from given _numberOfBcoupons and add it to the TO account.
        */
        balance_S_coupons[_to] = balance_S_coupons[_to].add(_numberOfScoupons.sub(transferCost));

        /*
        * log event.
        */
        Transfer_S_coupons(msg.sender, _to, _numberOfScoupons);
    }

    /*
    * Transfer residual B coupons to entities which integrates FedCoup.
    * It's investment on entities to integrate FedCoup on their sales lifecycle.
    */
    function transferResidualBcoupons(address _to, uint _numberOfBcoupons) onlyPayloadSize(2 * 32) onlyOwner {
        residualBcoupons = residualBcoupons.sub(_numberOfBcoupons);
        balance_B_coupons[_to] = balance_B_coupons[_to].add(_numberOfBcoupons);
        /* log event */
        TransferResidual_B_coupons(msg.sender, _to, _numberOfBcoupons);
    }

    /*
    * Transfer residual B coupons to entities which integrates FedCoup.
    * It's investment on entities to integrate FedCoup on their sales lifecycle.
    */
    function transferResidualScoupons(address _to, uint _numberOfScoupons) onlyPayloadSize(2 * 32) onlyOwner {
        residualScoupons = residualScoupons.sub(_numberOfScoupons);
        balance_S_coupons[_to] = balance_S_coupons[_to].add(_numberOfScoupons);
        /* log event */
        TransferResidual_B_coupons(msg.sender, _to, _numberOfScoupons);
    }

    /*
    * Get balance of S coupons.
    */
    function balanceOf_S_coupons(address _owner) constant returns (uint Sbalance) {
        return balance_S_coupons[_owner];
    }

    /*
    * Get balance of B coupons.
    */
    function balanceOf_B_coupons(address _owner) constant returns (uint Bbalance) {
        return balance_B_coupons[_owner];
    }

    /*
    * Get balance of residual B coupons.
    */
    function getBalanceOfResidualBcoupons() constant returns(uint residualBcoupons) {
        return residualBcoupons;
    }

    /*
    * Set FCC price function to get FCC price.
    */
    function setFCCPriceFunction(address addrFCCPriceFunc) onlyPayloadSize(2 * 32) onlyOwner {
        _fCCPriceFunction = FCCPrice(addrFCCPriceFunc);
    }

    /*
    *
    */

}


replace time with cost per assessor

replace time with cost per assessor

pragma solidity ^0.4.0;

import "userRegistry.sol";
import "concept.sol";
import "assessment.sol";
import "conceptRegistry.sol";

/*
@type: contract
@name: User
@purpose: To act as a representation for a user in the system
*/
contract User
{
  address user; //The address of the user's wallet
  address userRegistry; //The address of the userRegistry that spawned this user
  address conceptRegistry; //The address of the conceptRegistry
  string public userData; //An IPFS hash containing the user's data
  bool public availability;
  address[] public history;
  mapping (address => bool) public conceptPassed;
  mapping (address => Approval) transactApproved;
  mapping (address => Approval) assessApproved;
  struct Approval
  {
    bool approved;
    uint value; //fix stakes pls
  }

  /*
  @type: modifier
  @name: onlyUser
  @purpose: to only allow the user's wallet contract to call a function to which this modifier is applied
  */
  modifier onlyUser()
  {
    if(msg.sender != user) //checks if msg.sender has the same address as the user's wallet
    {
      throw; //throws the function call if not
    }
    _;
  }

  modifier onlyConcept()
  {
    if(ConceptRegistry(conceptRegistry).conceptExists(msg.sender) == false)
    {
      throw;
    }
    _;
  }
  /*
  @type: event
  @name: Notification
  @purpose: To provide a user with notifications
  */
  event Notification
  ( address _sender, //The notification sender
    address _user, //The address of the user that received the notification
    address _concept, //The address of the concept involved in this notification
    uint _code); //The notification code, see below for code guide:
    /*
    1 = Called As A Potential Assessor
    2 = Confirmed for assessing, stake has been taken
    3 = Assessment Cancled and you have been refunded
    4 = Assessment Has Started
    5 = Send in Score
    */

  /*
  @type: constructor function
  @purpose: To initialize the user contract
  @param: address userAddress = the address of the user's wallet
  @param: address userRegistryAddress = the address of the userRegistry that spawned this user
  @returns: nothing
  */
  function User(address _user, address _userRegistry, address _conceptRegistry)
  {
    user = _user; //Sets the user variable
    userRegistry = _userRegistry; //Sets the userRegistry variable
    conceptRegistry = _conceptRegistry; //Sets the conceptRegistry variable
  }

  /*
  @type: function
  @purpose: To set the availability of the user
  @param: bool available = the availability of the user
  @returns: nothing
  */
  function setAvailability(bool _availability) onlyUser()
  {
    availability = _availability;
  }

  function mapHistory(address assessment) onlyConcept()
  {
    history.push(assessment); //adds the address of the concept to the end of the array that is mapped to the user
  }

  /*
  @type: function
  @purpose: To confirm that a user is assessing or not assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint confirm = The user's confirmation code
  @returns: nothing
  */
  function confirmAssessment(address assessment) onlyUser()
  {
    Assessment(assessment).confirmAssessor(); //Sends the user's confromation to the assessmnet
  }

  /*
  @type: function
  @purpose: To send and IPFS hash to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: string data = the IPFS hash
  @returns: nothing
  */
  function setAssessmentData(address assessment, string data) onlyUser()
  {
    Assessment(assessment).setData(data); //Gives the assessment the IPFS hash
  }

  /*
  @type: function
  @purpose: To notify the assessment that the user is done assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @returns: nothing
  */
  function commit(address assessment, bytes32 hash) onlyUser()
  {
    Assessment(assessment).commit(hash); //Sets the user as done assessing in the assessment
  }

  /*
  @type: function
  @purpose: To send the score that the user has decided on to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint score = the score that the user decided on
  @returns: nothing
  */
  function reveal(address assessment, int8 score, bytes16 salt, address assessor) onlyUser()
  {
    Assessment(assessment).reveal(score,salt,assessor); //Sends to score to the assessment
  }

  /*
  @type: function
  @purpose: To send this user a notification
  @param: string description = the notification message
  @param: address concept = the address of the concept involved in this notification
  @param: uint code = the address of the concept involved in this notification
  @returns: nothing
  */
  function notification(address concept, uint code)
  {
    Notification(msg.sender, address(this), concept, code);
  }

  /*
  @type: function
  @purpose: To set the user's IPFS hash containing their information
  @param: string hash = IPFS hash containing the user information
  @returns: nothing
  */
  function setUserData(string hash) onlyUser()
  {
    userData = hash; //Sets userData to the hash value
  }

  function transferTokens(address user, uint amount) onlyUser() returns(bool)
  {
    return UserRegistry(userRegistry).transfer(user,amount);
  }

  function extTransferTokens(address user, uint amount) returns(bool)
  {
    if(transactApproved[msg.sender].approved = false)
    {
      return false;
    }
    else if(transactApproved[msg.sender].value > amount)
    {
      return false;
    }
    else
    {
      transactApproved[msg.sender].value -= amount;
      return UserRegistry(userRegistry).transfer(user,amount);
    }
  }

  function setConceptPassed(bool passed) onlyConcept()
  {
    conceptPassed[msg.sender] = passed;
  }

  function extMakeAssessment(address concept, uint cost, uint size) returns(bool)
  {
    if(assessApproved[msg.sender].approved == false)
    {
      return false;
    }
    else if(assessApproved[msg.sender].value > cost*size)
    {
      return false;
    }
    else
    {
      assessApproved[msg.sender].value -= cost*size;
      return Concept(concept).makeAssessment(cost, size);
    }
  }
}

pragma solidity ^0.4.0;

import "userRegistry.sol";
import "concept.sol";
import "assessment.sol";
import "conceptRegistry.sol";

/*
@type: contract
@name: User
@purpose: To act as a representation for a user in the system
*/
contract User
{
  address user; //The address of the user's wallet
  address userRegistry; //The address of the userRegistry that spawned this user
  address conceptRegistry; //The address of the conceptRegistry
  string public userData; //An IPFS hash containing the user's data
  bool public availability;
  address[] public history;
  mapping (address => bool) public conceptPassed;
  mapping (address => Approval) transactApproved;
  mapping (address => Approval) assessApproved;
  struct Approval
  {
    bool approved;
    uint value; //fix stakes pls
  }

  /*
  @type: modifier
  @name: onlyUser
  @purpose: to only allow the user's wallet contract to call a function to which this modifier is applied
  */
  modifier onlyUser()
  {
    if(msg.sender != user) //checks if msg.sender has the same address as the user's wallet
    {
      throw; //throws the function call if not
    }
    _;
  }

  modifier onlyConcept()
  {
    if(ConceptRegistry(conceptRegistry).conceptExists(msg.sender) == false)
    {
      throw;
    }
    _;
  }
  /*
  @type: event
  @name: Notification
  @purpose: To provide a user with notifications
  */
  event Notification
  ( address _sender, //The notification sender
    address _user, //The address of the user that received the notification
    address _concept, //The address of the concept involved in this notification
    uint _code); //The notification code, see below for code guide:
    /*
    1 = Called As A Potential Assessor
    2 = Confirmed for assessing, stake has been taken
    3 = Assessment Cancled and you have been refunded
    4 = Assessment Has Started
    5 = Send in Score
    */

  /*
  @type: constructor function
  @purpose: To initialize the user contract
  @param: address userAddress = the address of the user's wallet
  @param: address userRegistryAddress = the address of the userRegistry that spawned this user
  @returns: nothing
  */
  function User(address _user, address _userRegistry, address _conceptRegistry)
  {
    user = _user; //Sets the user variable
    userRegistry = _userRegistry; //Sets the userRegistry variable
    conceptRegistry = _conceptRegistry; //Sets the conceptRegistry variable
  }

  /*
  @type: function
  @purpose: To set the availability of the user
  @param: bool available = the availability of the user
  @returns: nothing
  */
  function setAvailability(bool _availability) onlyUser()
  {
    availability = _availability;
  }

  function mapHistory(address assessment) onlyConcept()
  {
    history.push(assessment); //adds the address of the concept to the end of the array that is mapped to the user
  }

  /*
  @type: function
  @purpose: To confirm that a user is assessing or not assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint confirm = The user's confirmation code
  @returns: nothing
  */
  function confirmAssessment(address assessment) onlyUser()
  {
    Assessment(assessment).confirmAssessor(); //Sends the user's confromation to the assessmnet
  }

  /*
  @type: function
  @purpose: To send and IPFS hash to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: string data = the IPFS hash
  @returns: nothing
  */
  function setAssessmentData(address assessment, string data) onlyUser()
  {
    Assessment(assessment).setData(data); //Gives the assessment the IPFS hash
  }

  /*
  @type: function
  @purpose: To notify the assessment that the user is done assessing
  @param: address assessment =  The assessment that the user has been called to assess
  @returns: nothing
  */
  function commit(address assessment, bytes32 hash) onlyUser()
  {
    Assessment(assessment).commit(hash); //Sets the user as done assessing in the assessment
  }

  /*
  @type: function
  @purpose: To send the score that the user has decided on to the assessment
  @param: address assessment =  The assessment that the user has been called to assess
  @param: uint score = the score that the user decided on
  @returns: nothing
  */
  function reveal(address assessment, int8 score, bytes16 salt, address assessor) onlyUser()
  {
    Assessment(assessment).reveal(score,salt,assessor); //Sends to score to the assessment
  }

  /*
  @type: function
  @purpose: To send this user a notification
  @param: string description = the notification message
  @param: address concept = the address of the concept involved in this notification
  @param: uint code = the address of the concept involved in this notification
  @returns: nothing
  */
  function notification(address concept, uint code)
  {
    Notification(msg.sender, address(this), concept, code);
  }

  /*
  @type: function
  @purpose: To set the user's IPFS hash containing their information
  @param: string hash = IPFS hash containing the user information
  @returns: nothing
  */
  function setUserData(string hash) onlyUser()
  {
    userData = hash; //Sets userData to the hash value
  }

  function transferTokens(address user, uint amount) onlyUser() returns(bool)
  {
    return UserRegistry(userRegistry).transfer(user,amount);
  }

  function extTransferTokens(address user, uint amount) returns(bool)
  {
    if(transactApproved[msg.sender].approved = false)
    {
      return false;
    }
    else if(transactApproved[msg.sender].value > amount)
    {
      return false;
    }
    else
    {
      transactApproved[msg.sender].value -= amount;
      return UserRegistry(userRegistry).transfer(user,amount);
    }
  }

  function setConceptPassed(bool passed) onlyConcept()
  {
    conceptPassed[msg.sender] = passed;
  }

  function extMakeAssessment(address concept, uint time, uint size) returns(bool)
  {
    if(assessApproved[msg.sender].approved == false)
    {
      return false;
    }
    else if(assessApproved[msg.sender].value > time*size)
    {
      return false;
    }
    else
    {
      assessApproved[msg.sender].value -= time*size;
      return Concept(concept).makeAssessment(time,size);
    }
  }
}


Address.functionCall internal call stack simplification (#3468)

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}