make VEN.isSealed external

make VEN.isSealed external

pragma solidity ^0.4.11;

import "./Token.sol";
import "./Owned.sol";
import "./SafeMath.sol";
import "./Prealloc.sol";

/// VEN token, ERC20 compliant
contract VEN is Token, Owned {
    using SafeMath for uint256;

    string public constant name    = "VeChain Token";  //The Token's name
    uint8 public constant decimals = 18;               //Number of decimals of the smallest unit
    string public constant symbol  = "VEN";            //An identifier

    struct Account {
        uint256 balance;
        // raw token can be transformed into balance with bonus
        uint256 rawTokens;
    }

    // Balances for each account
    mapping(address => Account) accounts;

    // Owner of account approves the transfer of an amount to another account
    mapping(address => mapping(address => uint256)) allowed;

    // every buying will update this var.
    // pre-alloc to make first buying cost no much more gas than subsequent
    using Prealloc for Prealloc.UINT256;
    Prealloc.UINT256 rawTokensSupplied;

    // bonus that can be shared by raw tokens
    uint256 bonusOffered;

    // Constructor
    function VEN() {
        rawTokensSupplied.set(0);
    }

    // Send back ether sent to me
    function () {
        revert();
    }

    // If sealed, transfer is enabled and mint is disabled
    function isSealed() constant returns (bool) {
        return owner == 0;
    }

    // Claim bonus by raw tokens
    function claimBonus(address _owner) internal{
        require(isSealed());
        if (accounts[_owner].rawTokens != 0) {
            accounts[_owner].balance = balanceOf(_owner);
            accounts[_owner].rawTokens = 0;
        }
    }

    // What is the balance of a particular account?
    function balanceOf(address _owner) constant returns (uint256 balance) {
        if (accounts[_owner].rawTokens == 0)
            return accounts[_owner].balance;

        if (isSealed()) {
            uint256 bonus =
                 accounts[_owner].rawTokens
                .mul(bonusOffered)
                .div(rawTokensSupplied.get());

            return accounts[_owner].balance
                    .add(accounts[_owner].rawTokens)
                    .add(bonus);
        }

        return accounts[_owner].balance.add(accounts[_owner].rawTokens);
    }

    // Transfer the balance from owner's account to another account
    function transfer(address _to, uint256 _amount) returns (bool success) {
        require(isSealed());

        // implicitly claim bonus for both sender and receiver
        claimBonus(msg.sender);
        claimBonus(_to);

        if (accounts[msg.sender].balance >= _amount
            && _amount > 0
            && accounts[_to].balance + _amount > accounts[_to].balance) {
            accounts[msg.sender].balance -= _amount;
            accounts[_to].balance += _amount;
            Transfer(msg.sender, _to, _amount);
            return true;
        } else {
            return false;
        }
    }

    // Send _value amount of tokens from address _from to address _to
    // The transferFrom method is used for a withdraw workflow, allowing contracts to send
    // tokens on your behalf, for example to "deposit" to a contract address and/or to charge
    // fees in sub-currencies; the command should fail unless the _from account has
    // deliberately authorized the sender of the message via some mechanism; we propose
    // these standardized APIs for approval:
    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    ) returns (bool success) {
        require(isSealed());

        // implicitly claim bonus for both sender and receiver
        claimBonus(_from);
        claimBonus(_to);

        if (accounts[_from].balance >= _amount
            && allowed[_from][msg.sender] >= _amount
            && _amount > 0
            && accounts[_to].balance + _amount > accounts[_to].balance) {
            accounts[_from].balance -= _amount;
            allowed[_from][msg.sender] -= _amount;
            accounts[_to].balance += _amount;
            Transfer(_from, _to, _amount);
            return true;
        } else {
            return false;
        }
    }

    // Allow _spender to withdraw from your account, multiple times, up to the _value amount.
    // If this function is called again it overwrites the current allowance with _value.
    function approve(address _spender, uint256 _amount) returns (bool success) {
        allowed[msg.sender][_spender] = _amount;
        Approval(msg.sender, _spender, _amount);
        return true;
    }

    /* Approves and then calls the receiving contract */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);

        //call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
        //receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
        //it is assumed that when does this that the call *should* succeed, otherwise one would use vanilla approve instead.
        //if(!_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { revert(); }
        ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

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

    // Mint tokens and assign to some one
    function mint(address _owner, uint256 _amount, bool _isRaw) onlyOwner{
        if (_isRaw) {
            accounts[_owner].rawTokens = accounts[_owner].rawTokens.add(_amount);
            rawTokensSupplied.set(rawTokensSupplied.get().add(_amount));
        } else {
            accounts[_owner].balance = accounts[_owner].balance.add(_amount);
        }

        totalSupply = totalSupply.add(_amount);
        Transfer(0, _owner, _amount);
    }

    // Offer bonus to raw tokens holder
    function offerBonus(uint256 _bonus) onlyOwner {
        bonusOffered = bonusOffered.add(_bonus);
    }

    // Set owner to zero address, to disable mint, and enable token transfer
    function seal() onlyOwner {
        setOwner(0);

        totalSupply = totalSupply.add(bonusOffered);
        Transfer(0, address(-1), bonusOffered);
    }
}

contract ApprovalReceiver {
    function receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData);
}

pragma solidity ^0.4.11;

import "./Token.sol";
import "./Owned.sol";
import "./SafeMath.sol";
import "./Prealloc.sol";

/// VEN token, ERC20 compliant
contract VEN is Token, Owned {
    using SafeMath for uint256;

    string public constant name    = "VeChain Token";  //The Token's name
    uint8 public constant decimals = 18;               //Number of decimals of the smallest unit
    string public constant symbol  = "VEN";            //An identifier

    struct Account {
        uint256 balance;
        // raw token can be transformed into balance with bonus
        uint256 rawTokens;
    }

    // Balances for each account
    mapping(address => Account) accounts;

    // Owner of account approves the transfer of an amount to another account
    mapping(address => mapping(address => uint256)) allowed;

    // every buying will update this var.
    // pre-alloc to make first buying cost no much more gas than subsequent
    using Prealloc for Prealloc.UINT256;
    Prealloc.UINT256 rawTokensSupplied;

    // bonus that can be shared by raw tokens
    uint256 bonusOffered;

    // Constructor
    function VEN() {
        rawTokensSupplied.set(0);
    }

    // Send back ether sent to me
    function () {
        revert();
    }

    // If sealed, transfer is enabled and mint is disabled
    function isSealed() internal constant returns (bool) {
        return owner == 0;
    }

    // Claim bonus by raw tokens
    function claimBonus(address _owner) internal{
        require(isSealed());
        if (accounts[_owner].rawTokens != 0) {
            accounts[_owner].balance = balanceOf(_owner);
            accounts[_owner].rawTokens = 0;
        }
    }

    // What is the balance of a particular account?
    function balanceOf(address _owner) constant returns (uint256 balance) {
        if (accounts[_owner].rawTokens == 0)
            return accounts[_owner].balance;

        if (isSealed()) {
            uint256 bonus =
                 accounts[_owner].rawTokens
                .mul(bonusOffered)
                .div(rawTokensSupplied.get());

            return accounts[_owner].balance
                    .add(accounts[_owner].rawTokens)
                    .add(bonus);
        }

        return accounts[_owner].balance.add(accounts[_owner].rawTokens);
    }

    // Transfer the balance from owner's account to another account
    function transfer(address _to, uint256 _amount) returns (bool success) {
        require(isSealed());

        // implicitly claim bonus for both sender and receiver
        claimBonus(msg.sender);
        claimBonus(_to);

        if (accounts[msg.sender].balance >= _amount
            && _amount > 0
            && accounts[_to].balance + _amount > accounts[_to].balance) {
            accounts[msg.sender].balance -= _amount;
            accounts[_to].balance += _amount;
            Transfer(msg.sender, _to, _amount);
            return true;
        } else {
            return false;
        }
    }

    // Send _value amount of tokens from address _from to address _to
    // The transferFrom method is used for a withdraw workflow, allowing contracts to send
    // tokens on your behalf, for example to "deposit" to a contract address and/or to charge
    // fees in sub-currencies; the command should fail unless the _from account has
    // deliberately authorized the sender of the message via some mechanism; we propose
    // these standardized APIs for approval:
    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    ) returns (bool success) {
        require(isSealed());

        // implicitly claim bonus for both sender and receiver
        claimBonus(_from);
        claimBonus(_to);

        if (accounts[_from].balance >= _amount
            && allowed[_from][msg.sender] >= _amount
            && _amount > 0
            && accounts[_to].balance + _amount > accounts[_to].balance) {
            accounts[_from].balance -= _amount;
            allowed[_from][msg.sender] -= _amount;
            accounts[_to].balance += _amount;
            Transfer(_from, _to, _amount);
            return true;
        } else {
            return false;
        }
    }

    // Allow _spender to withdraw from your account, multiple times, up to the _value amount.
    // If this function is called again it overwrites the current allowance with _value.
    function approve(address _spender, uint256 _amount) returns (bool success) {
        allowed[msg.sender][_spender] = _amount;
        Approval(msg.sender, _spender, _amount);
        return true;
    }

    /* Approves and then calls the receiving contract */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);

        //call the receiveApproval function on the contract you want to be notified. This crafts the function signature manually so one doesn't have to include a contract in here just for this.
        //receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
        //it is assumed that when does this that the call *should* succeed, otherwise one would use vanilla approve instead.
        //if(!_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { revert(); }
        ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }

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

    // Mint tokens and assign to some one
    function mint(address _owner, uint256 _amount, bool _isRaw) onlyOwner{
        if (_isRaw) {
            accounts[_owner].rawTokens = accounts[_owner].rawTokens.add(_amount);
            rawTokensSupplied.set(rawTokensSupplied.get().add(_amount));
        } else {
            accounts[_owner].balance = accounts[_owner].balance.add(_amount);
        }

        totalSupply = totalSupply.add(_amount);
        Transfer(0, _owner, _amount);
    }

    // Offer bonus to raw tokens holder
    function offerBonus(uint256 _bonus) onlyOwner {
        bonusOffered = bonusOffered.add(_bonus);
    }

    // Set owner to zero address, to disable mint, and enable token transfer
    function seal() onlyOwner {
        setOwner(0);

        totalSupply = totalSupply.add(bonusOffered);
        Transfer(0, address(-1), bonusOffered);
    }
}

contract ApprovalReceiver {
    function receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData);
}


Fix typo (#3016)

Fix typo (#3016)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/utils/SafeERC20.sol";

contract ERC20ReturnFalseMock is Context {
    uint256 private _allowance;

    // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
    // we write to a dummy state variable.
    uint256 private _dummy;

    function transfer(address, uint256) public returns (bool) {
        _dummy = 0;
        return false;
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public returns (bool) {
        _dummy = 0;
        return false;
    }

    function approve(address, uint256) public returns (bool) {
        _dummy = 0;
        return false;
    }

    function allowance(address, address) public view returns (uint256) {
        require(_dummy == 0); // Dummy read from a state variable so that the function is view
        return 0;
    }
}

contract ERC20ReturnTrueMock is Context {
    mapping(address => uint256) private _allowances;

    // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
    // we write to a dummy state variable.
    uint256 private _dummy;

    function transfer(address, uint256) public returns (bool) {
        _dummy = 0;
        return true;
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public returns (bool) {
        _dummy = 0;
        return true;
    }

    function approve(address, uint256) public returns (bool) {
        _dummy = 0;
        return true;
    }

    function setAllowance(uint256 allowance_) public {
        _allowances[_msgSender()] = allowance_;
    }

    function allowance(address owner, address) public view returns (uint256) {
        return _allowances[owner];
    }
}

contract ERC20NoReturnMock is Context {
    mapping(address => uint256) private _allowances;

    // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
    // we write to a dummy state variable.
    uint256 private _dummy;

    function transfer(address, uint256) public {
        _dummy = 0;
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public {
        _dummy = 0;
    }

    function approve(address, uint256) public {
        _dummy = 0;
    }

    function setAllowance(uint256 allowance_) public {
        _allowances[_msgSender()] = allowance_;
    }

    function allowance(address owner, address) public view returns (uint256) {
        return _allowances[owner];
    }
}

contract SafeERC20Wrapper is Context {
    using SafeERC20 for IERC20;

    IERC20 private _token;

    constructor(IERC20 token) {
        _token = token;
    }

    function transfer() public {
        _token.safeTransfer(address(0), 0);
    }

    function transferFrom() public {
        _token.safeTransferFrom(address(0), address(0), 0);
    }

    function approve(uint256 amount) public {
        _token.safeApprove(address(0), amount);
    }

    function increaseAllowance(uint256 amount) public {
        _token.safeIncreaseAllowance(address(0), amount);
    }

    function decreaseAllowance(uint256 amount) public {
        _token.safeDecreaseAllowance(address(0), amount);
    }

    function setAllowance(uint256 allowance_) public {
        ERC20ReturnTrueMock(address(_token)).setAllowance(allowance_);
    }

    function allowance() public view returns (uint256) {
        return _token.allowance(address(0), address(0));
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/utils/SafeERC20.sol";

contract ERC20ReturnFalseMock is Context {
    uint256 private _allowance;

    // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
    // we write to a dummy state variable.
    uint256 private _dummy;

    function transfer(address, uint256) public returns (bool) {
        _dummy = 0;
        return false;
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public returns (bool) {
        _dummy = 0;
        return false;
    }

    function approve(address, uint256) public returns (bool) {
        _dummy = 0;
        return false;
    }

    function allowance(address, address) public view returns (uint256) {
        require(_dummy == 0); // Duummy read from a state variable so that the function is view
        return 0;
    }
}

contract ERC20ReturnTrueMock is Context {
    mapping(address => uint256) private _allowances;

    // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
    // we write to a dummy state variable.
    uint256 private _dummy;

    function transfer(address, uint256) public returns (bool) {
        _dummy = 0;
        return true;
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public returns (bool) {
        _dummy = 0;
        return true;
    }

    function approve(address, uint256) public returns (bool) {
        _dummy = 0;
        return true;
    }

    function setAllowance(uint256 allowance_) public {
        _allowances[_msgSender()] = allowance_;
    }

    function allowance(address owner, address) public view returns (uint256) {
        return _allowances[owner];
    }
}

contract ERC20NoReturnMock is Context {
    mapping(address => uint256) private _allowances;

    // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
    // we write to a dummy state variable.
    uint256 private _dummy;

    function transfer(address, uint256) public {
        _dummy = 0;
    }

    function transferFrom(
        address,
        address,
        uint256
    ) public {
        _dummy = 0;
    }

    function approve(address, uint256) public {
        _dummy = 0;
    }

    function setAllowance(uint256 allowance_) public {
        _allowances[_msgSender()] = allowance_;
    }

    function allowance(address owner, address) public view returns (uint256) {
        return _allowances[owner];
    }
}

contract SafeERC20Wrapper is Context {
    using SafeERC20 for IERC20;

    IERC20 private _token;

    constructor(IERC20 token) {
        _token = token;
    }

    function transfer() public {
        _token.safeTransfer(address(0), 0);
    }

    function transferFrom() public {
        _token.safeTransferFrom(address(0), address(0), 0);
    }

    function approve(uint256 amount) public {
        _token.safeApprove(address(0), amount);
    }

    function increaseAllowance(uint256 amount) public {
        _token.safeIncreaseAllowance(address(0), amount);
    }

    function decreaseAllowance(uint256 amount) public {
        _token.safeDecreaseAllowance(address(0), amount);
    }

    function setAllowance(uint256 allowance_) public {
        ERC20ReturnTrueMock(address(_token)).setAllowance(allowance_);
    }

    function allowance() public view returns (uint256) {
        return _token.allowance(address(0), address(0));
    }
}


Fix 721 preset docs

Fix 721 preset docs

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "../access/AccessControl.sol";
import "../GSN/Context.sol";
import "../utils/Counters.sol";
import "../token/ERC721/ERC721.sol";
import "../token/ERC721/ERC721Burnable.sol";
import "../token/ERC721/ERC721Pausable.sol";

/**
 * @dev {ERC721} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *  - token ID and URI autogeneration
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts
 */
contract ERC721PresetMinterPauserAutoId is Context, AccessControl, ERC721Burnable, ERC721Pausable {
    using Counters for Counters.Counter;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    Counters.Counter private _tokenIdTracker;

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
     * account that deploys the contract.
     *
     * Token URIs will be autogenerated based on `baseURI` and their token IDs.
     * See {ERC721-tokenURI}.
     */
    constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());

        _setBaseURI(baseURI);
    }

    /**
     * @dev Creates a new token for `to`. Its token ID will be automatically
     * assigned (and available on the emitted {IERC721-Transfer} event), and the token
     * URI autogenerated based on the base URI passed at construction.
     *
     * See {ERC721-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");

        // We can just use balanceOf to create the new tokenId because tokens
        // can be burned (destroyed), so we need a separate counter.
        _mint(to, _tokenIdTracker.current());
        _tokenIdTracker.increment();
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function pause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
        _unpause();
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Pausable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "../access/AccessControl.sol";
import "../GSN/Context.sol";
import "../utils/Counters.sol";
import "../token/ERC721/ERC721.sol";
import "../token/ERC721/ERC721Burnable.sol";
import "../token/ERC721/ERC721Pausable.sol";

/**
 * @dev {ERC721} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *  - token ID and URI autogeneration
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts
 */
contract ERC721PresetMinterPauserAutoId is Context, AccessControl, ERC721Burnable, ERC721Pausable {
    using Counters for Counters.Counter;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    Counters.Counter private _tokenIdTracker;

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE` and `MINTER_ROLE` to the account that
     * deploys the contract.
     *
     * Token URIs will be autogenerated based on `baseURI` and their token IDs.
     * See {ERC721-tokenURI}.
     */
    constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());

        _setBaseURI(baseURI);
    }

    /**
     * @dev Creates a new token for `to`. Its token ID will be automatically
     * assigned (and available on the emitted {IERC721-Transfer} event), and the token
     * URI autogenerated based on the base URI passed at construction.
     *
     * See {ERC721-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");

        // We can just use balanceOf to create the new tokenId because tokens
        // can be burned (destroyed), so we need a separate counter.
        _mint(to, _tokenIdTracker.current());
        _tokenIdTracker.increment();
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function pause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
        _unpause();
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Pausable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }
}


Store the block number the blob is logged in in contract state.

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    mapping (bytes32 => uint) blobBlock;

    event logBlob(bytes32 indexed hash, bytes blob) anonymous;

    function getBlobBlock(bytes32 hash) constant returns (uint) {
        return blobBlock[hash];
    }

    function storeBlob(bytes blob) returns (bytes32 hash) {
        hash = sha3(blob);
        if (blobBlock[hash] != 0) {
            logBlob(hash, blob);
            blobBlock[hash] = block.number;
        }
    }

}

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    mapping (bytes32 => bool) stored;

    event logBlob(bytes32 indexed hash, bytes blob) anonymous;

    function isStored(bytes32 hash) constant returns (bool) {
        return stored[hash];
    }

    function storeBlob(bytes blob) returns (bytes32 hash) {
        hash = sha3(blob);
        if (!isStored(hash)) {
            logBlob(hash, blob);
            stored[hash] = true;
        }
    }

}


Fix MerkleProof natspec comments (#1083)

pragma solidity ^0.4.24;

/**
 * @title MerkleProof
 * @dev Merkle proof verification based on
 * https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol
 */
library MerkleProof {
  /**
   * @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves
   * and each pair of pre-images are sorted.
   * @param _proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree
   * @param _root Merkle root
   * @param _leaf Leaf of Merkle tree
   */
  function verifyProof(
    bytes32[] _proof,
    bytes32 _root,
    bytes32 _leaf
  )
    internal
    pure
    returns (bool)
  {
    bytes32 computedHash = _leaf;

    for (uint256 i = 0; i < _proof.length; i++) {
      bytes32 proofElement = _proof[i];

      if (computedHash < proofElement) {
        // Hash(current computed hash + current element of the proof)
        computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
      } else {
        // Hash(current element of the proof + current computed hash)
        computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
      }
    }

    // Check if the computed hash (root) is equal to the provided root
    return computedHash == _root;
  }
}

pragma solidity ^0.4.24;

/*
 * @title MerkleProof
 * @dev Merkle proof verification based on
 * https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol
 */
library MerkleProof {
  /*
   * @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves
   * and each pair of pre-images is sorted.
   * @param _proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree
   * @param _root Merkle root
   * @param _leaf Leaf of Merkle tree
   */
  function verifyProof(
    bytes32[] _proof,
    bytes32 _root,
    bytes32 _leaf
  )
    internal
    pure
    returns (bool)
  {
    bytes32 computedHash = _leaf;

    for (uint256 i = 0; i < _proof.length; i++) {
      bytes32 proofElement = _proof[i];

      if (computedHash < proofElement) {
        // Hash(current computed hash + current element of the proof)
        computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
      } else {
        // Hash(current element of the proof + current computed hash)
        computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
      }
    }

    // Check if the computed hash (root) is equal to the provided root
    return computedHash == _root;
  }
}


[TokenVesting] Rename events according to convention

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address beneficiary;

  uint256 cliff;
  uint256 start;
  uint256 duration;

  bool revocable;

  mapping (address => uint256) released;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != 0x0);
    require(_cliff < _duration);
    require(_start >= now);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start + _cliff;
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) {
    uint256 vested = vestedAmount(token);

    require(vested > 0);

    token.transfer(beneficiary, vested);

    released[token] = released[token].add(vested);

    Released(vested);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested remain in the contract.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) onlyOwner {
    require(revocable);

    uint256 balance = token.balanceOf(this);

    uint256 vested = vestedAmount(token);

    token.transfer(owner, balance - vested);

    Revoked();
  }

  /**
   * @dev Calculates the amount that has already vested but not released.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) constant returns (uint256) {
    if (now < cliff) {
      return 0;
    } else if (now >= start + duration) {
      return token.balanceOf(this);
    } else {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);

      uint256 vested = totalBalance.mul(now - start).div(duration);
      uint256 unreleased = vested.sub(released[token]);

      // currentBalance can be 0 in case of a revoke
      return Math.min256(currentBalance, unreleased);
    }
  }
}

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;

  event Release(uint256 amount);
  event Revoke();

  // beneficiary of tokens after they are released
  address beneficiary;

  uint256 cliff;
  uint256 start;
  uint256 duration;

  bool revocable;

  mapping (address => uint256) released;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != 0x0);
    require(_cliff < _duration);
    require(_start >= now);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start + _cliff;
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) {
    uint256 vested = vestedAmount(token);

    require(vested > 0);

    token.transfer(beneficiary, vested);

    released[token] = released[token].add(vested);

    Release(vested);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested remain in the contract.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) onlyOwner {
    require(revocable);

    uint256 balance = token.balanceOf(this);

    uint256 vested = vestedAmount(token);

    token.transfer(owner, balance - vested);

    Revoke();
  }

  /**
   * @dev Calculates the amount that has already vested but not released.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) constant returns (uint256) {
    if (now < cliff) {
      return 0;
    } else if (now >= start + duration) {
      return token.balanceOf(this);
    } else {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);

      uint256 vested = totalBalance.mul(now - start).div(duration);
      uint256 unreleased = vested.sub(released[token]);

      // currentBalance can be 0 in case of a revoke
      return Math.min256(currentBalance, unreleased);
    }
  }
}


Allow multiple contributions to an address during the presale distribution

pragma solidity ^0.4.15;
import './Utils.sol';
import './Owned.sol';

contract ENJToken {
    function balanceOf(address _owner) public constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) public returns (bool success);
    function totalAllocated() constant public returns (uint256 allocated);
    function addToAllocation(uint256 _amount);
}

contract ENJCrowdfund is Utils, Owned {

///////////////////////////////////////// VARIABLE INITIALIZATION /////////////////////////////////////////

    uint256 public startTime = 1507032000;              // 10/03/2017 @ 12:00pm (UTC) crowdsale start time (in seconds)
    uint256 public endTime = 1509494340;                // 10/31/2017 @ 11:59pm (UTC) crowdsale end time (in seconds)
    uint256 internal week2Start = startTime + (7 days);   // 10/10/2017 @ 12:00pm (UTC) week 2 price begins
    uint256 internal week3Start = week2Start + (7 days);  // 10/17/2017 @ 12:00pm (UTC) week 3 price begins
    uint256 internal week4Start = week3Start + (7 days);  // 10/25/2017 @ 12:00pm (UTC) week 4 price begins

    uint256 public totalPresaleTokensYetToAllocate;     // Counter that keeps track of presale tokens yet to allocate
    address public beneficiary = 0x0;                   // address to receive all ether contributions
    address public tokenAddress = 0x0;                  // address to receive all ether contributions

    ENJToken token;                                     // ENJ Token interface

///////////////////////////////////////// EVENTS /////////////////////////////////////////

    event CrowdsaleContribution(address indexed _contributor, uint256 _amount, uint256 _return);
    event PresaleContribution(address indexed _contributor, uint256 _amountOfTokens);

///////////////////////////////////////// CONSTRUCTOR /////////////////////////////////////////

    /**
        @dev constructor
        @param _totalPresaleTokensYetToAllocate     Total amount of presale tokens sold
        @param _beneficiary                         Address that will be receiving the ETH contributed
    */
    function ENJCrowdfund(uint256 _totalPresaleTokensYetToAllocate, address _beneficiary)
    validAddress(_beneficiary)
    {
        totalPresaleTokensYetToAllocate = _totalPresaleTokensYetToAllocate;
        beneficiary = _beneficiary;
    }

///////////////////////////////////////// MODIFIERS /////////////////////////////////////////

    // Ensures that the current time is between startTime (inclusive) and endTime (exclusive)
    modifier between() {
        assert(now >= startTime && now < endTime);
        _;
    }

    // Ensures the current time is after the crowdfund
    modifier afterCrowdfund() {
        assert(now >= endTime);
        _;
    }

    // Ensures the Token address is set
    modifier tokenIsSet() {
        require(tokenAddress != 0x0);
        _;
    }

///////////////////////////////////////// OWNER FUNCTIONS /////////////////////////////////////////

    /**
        @dev Sets the ENJ Token address
        Can only be called once by the owner
        @param _tokenAddress    ENJ Token Address
    */
    function setToken(address _tokenAddress) validAddress(_tokenAddress) ownerOnly {
        require(tokenAddress == 0x0);
        tokenAddress = _tokenAddress;
        token = ENJToken(_tokenAddress);
    }

    /**
        @dev Sets a new Beneficiary address
        Can only be called once by the owner
        @param _newBeneficiary    Beneficiary Address
    */
    function changeBeneficiary(address _newBeneficiary) validAddress(_newBeneficiary) ownerOnly {
        beneficiary = _newBeneficiary;
    }

    /**
        @dev Function to send ENJ to presale investors
        Can only be called while the presale is not over. Any multiple contribution from the same address
        will be aggregated.
        @param _batchOfAddresses list of addresses
        @param _amountofENJ matching list of address balances
    */
    function deliverPresaleTokens(address[] _batchOfAddresses, uint256[] _amountofENJ) external tokenIsSet ownerOnly returns (bool success) {
        require(now < startTime);
        for (uint256 i = 0; i < _batchOfAddresses.length; i++) {
            deliverPresaleTokenToClient(_batchOfAddresses[i], _amountofENJ[i]);
        }
        return true;
    }

    /**
        @dev Logic to transfer presale tokens
        Can only be called while the there are leftover presale tokens to allocate. Any multiple contribution from
        the same address will be aggregated.
        @param _accountHolder user address
        @param _amountofENJ balance to send out
    */
    function deliverPresaleTokenToClient(address _accountHolder, uint256 _amountofENJ) internal ownerOnly {
        require(totalPresaleTokensYetToAllocate > 0);
        token.transfer(_accountHolder, _amountofENJ);
        token.addToAllocation(_amountofENJ);
        totalPresaleTokensYetToAllocate = safeSub(totalPresaleTokensYetToAllocate, _amountofENJ);
        PresaleContribution(_accountHolder, _amountofENJ);
    }

///////////////////////////////////////// PUBLIC FUNCTIONS /////////////////////////////////////////
    /**
        @dev ETH contribution function
        Can only be called during the crowdsale. Also allows a person to buy tokens for another address

        @return tokens issued in return
    */
    function contributeETH(address _to) public validAddress(_to) between tokenIsSet payable returns (uint256 amount) {
        return processContribution(_to);
    }

    /**
        @dev handles contribution logic
        note that the Contribution event is triggered using the sender as the contributor, regardless of the actual contributor

        @return tokens issued in return
    */
    function processContribution(address _to) private returns (uint256 amount) {

        uint256 tokenAmount = getTotalAmountOfTokens(msg.value);
        beneficiary.transfer(msg.value);
        token.transfer(_to, tokenAmount);
        token.addToAllocation(tokenAmount);
        CrowdsaleContribution(_to, msg.value, tokenAmount);
        return tokenAmount;
    }

///////////////////////////////////////// CONSTANT FUNCTIONS /////////////////////////////////////////

    /**
        @dev Returns total tokens allocated so far
        Constant function that simply returns a number

        @return total tokens allocated so far
    */
    function totalEnjSold() public constant returns(uint256 total) {
        return token.totalAllocated();
    }

    /**
        @dev computes the number of tokens that should be issued for a given contribution
        @param _contribution    contribution amount
        @return computed number of tokens
    */
    function getTotalAmountOfTokens(uint256 _contribution) public constant returns (uint256 amountOfTokens) {
        uint256 currentTokenPrice = 0;
        if (now < week2Start) {
            return currentTokenPrice = safeMul(_contribution, 6000);
        } else if (now < week3Start) {
            return currentTokenPrice = safeMul(_contribution, 5000);
        } else if (now < week4Start) {
            return currentTokenPrice = safeMul(_contribution, 4000);
        } else {
            return currentTokenPrice = safeMul(_contribution, 3000);
        }

    }

    /**
        @dev Fallback function
        Main entry to buy into the crowdfund, all you need to do is send a value transaction
        to this contract address. Please include at least 100 000 gas in the transaction.
    */
    function() payable {
        contributeETH(msg.sender);
    }
}

pragma solidity ^0.4.15;
import './Utils.sol';
import './Owned.sol';

contract ENJToken {
    function balanceOf(address _owner) public constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) public returns (bool success);
    function totalAllocated() constant public returns (uint256 allocated);
    function addToAllocation(uint256 _amount);
}

contract ENJCrowdfund is Utils, Owned {

///////////////////////////////////////// VARIABLE INITIALIZATION /////////////////////////////////////////

    uint256 public startTime = 1507032000;              // 10/03/2017 @ 12:00pm (UTC) crowdsale start time (in seconds)
    uint256 public endTime = 1509494340;                // 10/31/2017 @ 11:59pm (UTC) crowdsale end time (in seconds)
    uint256 internal week2Start = startTime + (7 days);   // 10/10/2017 @ 12:00pm (UTC) week 2 price begins
    uint256 internal week3Start = week2Start + (7 days);  // 10/17/2017 @ 12:00pm (UTC) week 3 price begins
    uint256 internal week4Start = week3Start + (7 days);  // 10/25/2017 @ 12:00pm (UTC) week 4 price begins

    uint256 public totalPresaleTokensYetToAllocate;     // Counter that keeps track of presale tokens yet to allocate
    address public beneficiary = 0x0;                   // address to receive all ether contributions
    address public tokenAddress = 0x0;                  // address to receive all ether contributions

    ENJToken token;                                     // ENJ Token interface

///////////////////////////////////////// EVENTS /////////////////////////////////////////

    event CrowdsaleContribution(address indexed _contributor, uint256 _amount, uint256 _return);
    event PresaleContribution(address indexed _contributor, uint256 _amountOfTokens);

///////////////////////////////////////// CONSTRUCTOR /////////////////////////////////////////

    /**
        @dev constructor
        @param _totalPresaleTokensYetToAllocate          smart token the crowdsale is for
        @param _beneficiary    address to receive all ether contributions
    */
    function ENJCrowdfund(uint256 _totalPresaleTokensYetToAllocate, address _beneficiary)
    validAddress(_beneficiary)
    {
        totalPresaleTokensYetToAllocate = _totalPresaleTokensYetToAllocate;     // Input total amount of presale tokens sold
        beneficiary = _beneficiary;                                             // Address that will be receiving the ETH contributed
    }

///////////////////////////////////////// MODIFIERS /////////////////////////////////////////

    // Ensures that the current time is between startTime (inclusive) and endTime (exclusive)
    modifier between() {
        assert(now >= startTime && now < endTime);
        _;
    }

    // Ensures the current time is after the crowdfund
    modifier afterCrowdfund() {
        assert(now >= endTime);
        _;
    }

    // Ensures the Token address is set
    modifier tokenIsSet() {
        require(tokenAddress != 0x0);
        _;
    }

///////////////////////////////////////// OWNER FUNCTIONS /////////////////////////////////////////

    /**
        @dev Sets the ENJ Token address
        Can only be called once by the owner
        @param _tokenAddress    ENJ Token Address
    */
    function setToken(address _tokenAddress) validAddress(_tokenAddress) ownerOnly {
        require(tokenAddress == 0x0);
        tokenAddress = _tokenAddress;
        token = ENJToken(_tokenAddress);
    }

    /**
        @dev Sets a new Beneficiary address
        Can only be called once by the owner
        @param _newBeneficiary    Beneficiary Address
    */
    function changeBeneficiary(address _newBeneficiary) validAddress(_newBeneficiary) ownerOnly {
        beneficiary = _newBeneficiary;
    }

    /**
        @dev Function to send ENJ to presale investors
        Can only be called while the presale is not over. Any multiple contribution from the same address
        will be aggregated.
        @param _batchOfAddresses list of addresses
        @param _amountofENJ matching list of address balances
    */
    function deliverPresaleTokens(address[] _batchOfAddresses, uint256[] _amountofENJ) external tokenIsSet ownerOnly returns (bool success) {
        require(now < startTime);
        for (uint256 i = 0; i < _batchOfAddresses.length; i++) {
            deliverPresaleTokenToClient(_batchOfAddresses[i], _amountofENJ[i]);
        }
        return true;
    }

    /**
        @dev Logic to transfer presale tokens
        Can only be called while the there are leftover presale tokens to allocate. Any multiple contribution from
        the same address will be aggregated.
        @param _accountHolder user address
        @param _amountofENJ balance to send out
    */
    function deliverPresaleTokenToClient(address _accountHolder, uint256 _amountofENJ) internal ownerOnly {
        require(token.balanceOf(_accountHolder) == 0 && totalPresaleTokensYetToAllocate > 0);
        token.transfer(_accountHolder, _amountofENJ);
        token.addToAllocation(_amountofENJ);
        totalPresaleTokensYetToAllocate = safeSub(totalPresaleTokensYetToAllocate, _amountofENJ);
        PresaleContribution(_accountHolder, _amountofENJ);
    }

///////////////////////////////////////// PUBLIC FUNCTIONS /////////////////////////////////////////
    /**
        @dev ETH contribution function
        Can only be called during the crowdsale. Also allows a person to buy tokens for another address

        @return tokens issued in return
    */
    function contributeETH(address _to) public validAddress(_to) between tokenIsSet payable returns (uint256 amount) {
        return processContribution(_to);
    }

    /**
        @dev handles contribution logic
        note that the Contribution event is triggered using the sender as the contributor, regardless of the actual contributor

        @return tokens issued in return
    */
    function processContribution(address _to) private returns (uint256 amount) {

        uint256 tokenAmount = getTotalAmountOfTokens(msg.value);
        beneficiary.transfer(msg.value);
        token.transfer(_to, tokenAmount);
        token.addToAllocation(tokenAmount);
        CrowdsaleContribution(_to, msg.value, tokenAmount);
        return tokenAmount;
    }

///////////////////////////////////////// CONSTANT FUNCTIONS /////////////////////////////////////////

    /**
        @dev Returns total tokens allocated so far
        Constant function that simply returns a number

        @return total tokens allocated so far
    */
    function totalEnjSold() public constant returns(uint256 total) {
        return token.totalAllocated();
    }

    /**
        @dev computes the number of tokens that should be issued for a given contribution
        @param _contribution    contribution amount
        @return computed number of tokens
    */
    function getTotalAmountOfTokens(uint256 _contribution) public constant returns (uint256 amountOfTokens) {
        uint256 currentTokenPrice = 0;
        if (now < week2Start) {
            return currentTokenPrice = safeMul(_contribution, 6000);
        } else if (now < week3Start) {
            return currentTokenPrice = safeMul(_contribution, 5000);
        } else if (now < week4Start) {
            return currentTokenPrice = safeMul(_contribution, 4000);
        } else {
            return currentTokenPrice = safeMul(_contribution, 3000);
        }

    }

    /**
        @dev Fallback function
        Main entry to buy into the crowdfund, all you need to do is send a value transaction
        to this contract address. Please include at least 100 000 gas in the transaction.
    */
    function() payable {
        contributeETH(msg.sender);
    }
}


fixed loop

fixed loop

pragma solidity ^0.4.0;

/*
@type: contract
@name: Math
@purpose: To provide a library of math functions
*/

library Math {
    uint constant maxAssessors = 200;
  /*
  @purpose: To generate a weak random number between 0 and the specified maximum
  @param: uint seed = seed number for the generation of a random number
  @param: uint max = the max for the range of random numbers that can be made
  @returns: The random number
  */
  function getRandom(uint seed, uint max) constant returns(uint) { //Based on the function by alexvandesande
    return(uint(sha3(block.blockhash(block.number-1), seed))%(max+1)); //Hashes the seed number with the last blockhash to generate a random number and shifts it into the desired range by using a modulus
  }

  /*
  @purpose: To generate a weak random number between a specified minimum and the specified maximum
  @param: uint seed = seed number for the generation of a random number
  @param: uint max = the max for the range of random numbers that can be made
  @param: uint min = the min for the range of random numbers that can be made
  @returns: The random number
  */
  function getRandom(uint seed, uint min, uint max) constant returns(uint) {
    return(uint(sha3(block.blockhash(block.number-1), seed))%(max-min+1) + min); //Hashes the seed number with the last blockhash to generate a random number and shifts it into the desired range by using a modulus and addition
  }

  function calculateMAD(int[] data) constant returns(int) {
    int mean;
    int totalRelativeDistance;
    int meanAbsoluteDeviation;
    for(uint j = 0; j < data.length; j++) {
      mean += data[j];
    }
    mean /=  int(data.length);
    for(uint k = 0; k < data.length; k++) {
      int distanceFromMean = data[k] - mean;
      if(distanceFromMean < 0) {
        distanceFromMean *= -1;
      }
      totalRelativeDistance += distanceFromMean;
    }
    meanAbsoluteDeviation = totalRelativeDistance/int(data.length);
    return meanAbsoluteDeviation;
  }

  function getLargestCluster(int[] data) returns(bool[200], uint) {
      uint largestClusterSize = 0;
      bool[200] memory largestCluster;
      int MAD = calculateMAD(data);
      for(uint i=0; i < data.length; i++) {
          uint clusterSize = 0;
          bool[200] memory cluster;
          for (uint j = 0; j < data.length; j++){
              if(abs(data[i] - data[j]) <= MAD ){
                  cluster[j] = true;
                  clusterSize++;
              }
          }
          if(clusterSize > largestClusterSize) {
              largestCluster = cluster;
              largestClusterSize = clusterSize;
          }
      }
      return (largestCluster, largestClusterSize);
  }

  function abs(int x) returns (int256){
      if( x < 0 ) { return -1*x;}
      else { return x;}
  }
}

pragma solidity ^0.4.0;

/*
@type: contract
@name: Math
@purpose: To provide a library of math functions
*/

library Math {
    uint constant maxAssessors = 200;
  /*
  @purpose: To generate a weak random number between 0 and the specified maximum
  @param: uint seed = seed number for the generation of a random number
  @param: uint max = the max for the range of random numbers that can be made
  @returns: The random number
  */
  function getRandom(uint seed, uint max) constant returns(uint) { //Based on the function by alexvandesande
    return(uint(sha3(block.blockhash(block.number-1), seed))%(max+1)); //Hashes the seed number with the last blockhash to generate a random number and shifts it into the desired range by using a modulus
  }

  /*
  @purpose: To generate a weak random number between a specified minimum and the specified maximum
  @param: uint seed = seed number for the generation of a random number
  @param: uint max = the max for the range of random numbers that can be made
  @param: uint min = the min for the range of random numbers that can be made
  @returns: The random number
  */
  function getRandom(uint seed, uint min, uint max) constant returns(uint) {
    return(uint(sha3(block.blockhash(block.number-1), seed))%(max-min+1) + min); //Hashes the seed number with the last blockhash to generate a random number and shifts it into the desired range by using a modulus and addition
  }

  function calculateMAD(int[] data) constant returns(int) {
    int mean;
    int totalRelativeDistance;
    int meanAbsoluteDeviation;
    for(uint j = 0; j < data.length; j++) {
      mean += data[j];
    }
    mean /=  int(data.length);
    for(uint k = 0; k < data.length; k++) {
      int distanceFromMean = data[k] - mean;
      if(distanceFromMean < 0) {
        distanceFromMean *= -1;
      }
      totalRelativeDistance += distanceFromMean;
    }
    meanAbsoluteDeviation = totalRelativeDistance/int(data.length);
    return meanAbsoluteDeviation;
  }

  function getLargestCluster(int[] data) returns(bool[200], uint) {
      uint largestClusterSize = 0;
      bool[200] memory largestCluster;
      int MAD = calculateMAD(data);
      for(uint i=0; i < data.length; i++) {
          uint clusterSize = 0;
          bool[200] memory cluster;
          for (uint j = 0; j < data.length; j++){
              if(abs(data[i] - data[j]) <= MAD ){
                  cluster[j] = true;
                  clusterSize++;
              }
              if(clusterSize > largestClusterSize) {
                  largestCluster = cluster;
                  largestClusterSize = clusterSize;
              }
          }
      }
      return (largestCluster, largestClusterSize);
  }

  function abs(int x) returns (int256){
      if( x < 0 ) { return -1*x;}
      else { return x;}
  }
}


Add 'Internal' to fix access control of functions

pragma solidity^0.4.11;

import "../libraries/TreeLib.sol";

contract Tree{

    mapping(bytes32=>TreeLib.Index) indexes;//Or a single index, based on how you want to arange your indexes
    mapping(bytes32=>bytes32) parent_child_lookup;

    uint max_depth=2; // Maxdepth of the tree; advised 5
    uint mtypes_count=3;//Count of mtypes,available structure types from the lib
    bytes8[3] mtypes = [ bytes8("Node"), bytes8("Section"), bytes8("Index")]; //Increase type to match structure types
    enum ltypes {Node,Section,Index} //Increase type to match structure types

    uint parent_max_size = 10; //Max size for all parents equaling Max nodes = parent_max_size^(max_depth-1)

    function TreeContract(){
    }

    function indexExists(bytes32 index_id) constant returns (bool){
        return (indexes[index_id].id == index_id);
    }

    function childExists(bytes32 child_id) constant returns(bool){
        return (getParent(child_id) != 0x0);
    }

    function nodeExists(bytes32 index_id,bytes32 node_id) constant returns(bool){
        if(childExists(node_id) ){
          return getHeirachy(node_id)[1] == index_id;
        }
        return false;
    }

    function getParent(bytes32 child_id) constant returns(bytes32){
        return parent_child_lookup[child_id];
    }

    function getHeirachy(bytes32 child_id) constant returns (bytes32[2] memory search_up /*should match (max_depth)*/){
        bytes32 main_index_id;

        //Fetch the node's parent
        main_index_id = getParent(child_id);
        search_up[0] = main_index_id;

        uint i = 1;
        while((main_index_id = getParent(main_index_id)) != 0x0){
        search_up[i] = main_index_id;
        i++;
        }
    }

    function nextSection(bytes32 index_id) internal constant returns (bytes32 id){
      //get the next available section in the index
      TreeLib.Index storage index = indexes[index_id];
      id = indexes[index_id].root;
      while(true){
        if(index.children[id].size+1 > index.maxsize && index.children[id].id != 0x0){
          id = index.children[id].right;
          continue;
        }
        else break;
      }
      return id;
    }

    function getSection(bytes32 section_id) internal constant returns(TreeLib.Section storage sector){
        bytes32[2] memory search_up; //size should match (max_depth)
        search_up = getHeirachy(section_id);

        //GenecricTree.SubSection storage subsector; //Only enabled if max_dept >2
        //Structure based on sector parent being index
        if(search_up.length>0){
          sector = indexes[search_up[0]].children[section_id];
        }
    }

    function getIndex(bytes32 index_id)constant returns(uint mtype,uint size, uint maxsize, bytes32 id, bytes32 root, bytes32 last){

        TreeLib.Index memory index = indexes[index_id];
        return (index.mtype,index.size,index.maxsize,index.id,index.root,index.last);
    }

    function getNode(bytes32 node_id) constant returns (bytes32 id,bytes32 left,bytes32 right,bytes32 parent,bytes32 data){
        //set returns based on nature of base node
        //require(child_type_lookup[node_id] == ltypes.Node);
        return TreeLib.getNode(getSection(getParent(node_id)),node_id);
    }

    function getNodesBatch(bytes32 index_id,bytes32 last_node_id) constant returns (bytes32[5][5] results) {
          TreeLib.Index storage index = indexes[index_id];

          //throw if empty
          require(index.size>0);

          if(last_node_id == 0x0)last_node_id = index.children[index.root].root;
          else last_node_id = index.children[getParent(last_node_id)].children[last_node_id].right;

          bytes32 section_id = getParent(last_node_id);
          TreeLib.Section storage sector = index.children[section_id];

          uint r = 0;

          while(r<5 && last_node_id!=0x0){
           results[0][r]= sector.children[last_node_id].id;
           results[1][r]= sector.children[last_node_id].left;
           results[2][r]= sector.children[last_node_id].right;
           results[3][r]= sector.children[last_node_id].parent;
           results[4][r]= sector.children[last_node_id].data;
           r++;

           if(sector.children[last_node_id].right == 0x0){
             if(sector.right != 0x0){
               sector = index.children[sector.right];
               last_node_id = sector.root;
               continue;
             }
           break;
           }
           else {
             last_node_id = sector.children[last_node_id].right;}
          }

          return results;
    }

    function removeSection(bytes32 index_id,bytes32 section_id) internal idNotEmpty(section_id){
      assert(getParent(section_id) == index_id);
      TreeLib.Index storage index = indexes[index_id];
      delete(parent_child_lookup[section_id]);
      TreeLib.removeSection(index,section_id);
    }

    function removeNode(bytes32 index_id,bytes32 node_id) idNotEmpty(node_id){
      bytes32 section_id = getParent(node_id);
      assert(getParent(section_id) == index_id);
      TreeLib.Section storage sector = getSection(section_id);

      delete(parent_child_lookup[node_id]);
      TreeLib.removeNode(sector,node_id);

      if(sector.size == 0)
      removeSection(index_id,section_id);
    }

    function generateSection() internal constant returns (bytes32 section_id){
      uint i = 0;
      while(childExists(sha3(block.difficulty+i,block.number+i,block.timestamp+1))){
        i++;
      }
      return sha3(block.difficulty+i,block.number+i,block.timestamp+1);
    }

    function newIndex(bytes32 index_id) internal idNotEmpty(index_id){
        indexes[index_id] = TreeLib.newIndex(index_id,parent_max_size);
    }

    function insertSection(bytes32 parent_id) internal returns(bytes32){
        //Create new index, if it does not exist
        if(!indexExists(parent_id))
          newIndex(parent_id);

        bytes32 section_id = generateSection();

        //Parent is an Index, store as child of index
        TreeLib.Index storage index = indexes[parent_id];
        parent_child_lookup[section_id] =  parent_id;
        TreeLib.insertSection(index,section_id);
        return section_id;
    }

    function insertNode(bytes32 index_id, bytes32 node_id, bytes32 data){
        //Ensure index and node are not empty
        require(index_id!= 0x0 && node_id != 0x0);

        //Create new index, if it does not exist
        if(!indexExists(index_id))
          newIndex(index_id);

        //check to see the next available sector
        bytes32 section_id = nextSection(index_id);
        if(section_id == 0x0)
          section_id = insertSection(index_id);

        parent_child_lookup[node_id] =  section_id;
        TreeLib.insertNode(getSection(section_id),node_id,data);
    }

    function insertNodeBatch(bytes32 index_id, bytes32[2][5] data){
      require(index_id!= 0x0);

      //Create new index, if it does not exist
      if(!indexExists(index_id))
        newIndex(index_id);

      //check to see the next available sector
      bytes32 section_id = nextSection(index_id);
      if(section_id == 0x0)
        section_id = insertSection(index_id);
      uint to_fill = indexes[index_id].children[section_id].maxsize - indexes[index_id].children[section_id].size;

      for(uint d=0;d<data.length;d++){
        bytes32 node_id = data[d][0];
        bytes32 node_data = data[d][1];
        //Ensure index and node are not empty
        if(node_id == 0x0)
        continue;

        //Generate new sector if exceeded
        if(to_fill < d+1){
          section_id = nextSection(index_id);
          if(section_id == 0x0)
            section_id = insertSection(index_id);
          to_fill += indexes[index_id].children[section_id].maxsize - indexes[index_id].children[section_id].size;
        }

        bytes32 right = 0x0;
        bytes32 left = 0x0;
        if(d==0){
          TreeLib.Section storage sector = getSection(section_id);
          left = sector.last;
          sector.children[left].right = node_id;
        }
        else{
          left = data[d-1][0];
        }
        if(data.length>d+1)
          right = data[d+1][0];

        parent_child_lookup[node_id] =  section_id;
        TreeLib.insertNodeBatch(getSection(section_id),left,right,node_id,node_data);
      }
    }

    modifier idNotEmpty(bytes32 id){
        require(id != 0x0);
        _;
    }

}

pragma solidity^0.4.11;

import "../libraries/TreeLib.sol";

contract Tree{

    mapping(bytes32=>TreeLib.Index) indexes;//Or a single index, based on how you want to arange your indexes
    mapping(bytes32=>bytes32) parent_child_lookup;

    uint max_depth=2; // Maxdepth of the tree; advised 5
    uint mtypes_count=3;//Count of mtypes,available structure types from the lib
    bytes8[3] mtypes = [ bytes8("Node"), bytes8("Section"), bytes8("Index")]; //Increase type to match structure types
    enum ltypes {Node,Section,Index} //Increase type to match structure types

    uint parent_max_size = 10; //Max size for all parents equaling Max nodes = parent_max_size^(max_depth-1)

    function TreeContract(){
    }

    function indexExists(bytes32 index_id) constant returns (bool){
        return (indexes[index_id].id == index_id);
    }

    function childExists(bytes32 child_id) constant returns(bool){
        return (getParent(child_id) != 0x0);
    }

    function nodeExists(bytes32 index_id,bytes32 node_id) constant returns(bool){
        if(childExists(node_id) ){
          return getHeirachy(node_id)[1] == index_id;
        }
        return false;
    }

    function getParent(bytes32 child_id) constant returns(bytes32){
        return parent_child_lookup[child_id];
    }

    function getHeirachy(bytes32 child_id) constant returns (bytes32[2] memory search_up /*should match (max_depth)*/){
        bytes32 main_index_id;

        //Fetch the node's parent
        main_index_id = getParent(child_id);
        search_up[0] = main_index_id;

        uint i = 1;
        while((main_index_id = getParent(main_index_id)) != 0x0){
        search_up[i] = main_index_id;
        i++;
        }
    }

    function nextSection(bytes32 index_id) internal constant returns (bytes32 id){
      //get the next available section in the index
      TreeLib.Index storage index = indexes[index_id];
      id = indexes[index_id].root;
      while(true){
        if(index.children[id].size+1 > index.maxsize && index.children[id].id != 0x0){
          id = index.children[id].right;
          continue;
        }
        else break;
      }
      return id;
    }

    function getSection(bytes32 section_id) internal constant returns(TreeLib.Section storage sector){
        bytes32[2] memory search_up; //size should match (max_depth)
        search_up = getHeirachy(section_id);

        //GenecricTree.SubSection storage subsector; //Only enabled if max_dept >2
        //Structure based on sector parent being index
        if(search_up.length>0){
          sector = indexes[search_up[0]].children[section_id];
        }
    }

    function getIndex(bytes32 index_id)constant returns(uint mtype,uint size, uint maxsize, bytes32 id, bytes32 root, bytes32 last){

        TreeLib.Index memory index = indexes[index_id];
        return (index.mtype,index.size,index.maxsize,index.id,index.root,index.last);
    }

    function getNode(bytes32 node_id) constant returns (bytes32 id,bytes32 left,bytes32 right,bytes32 parent,bytes32 data){
        //set returns based on nature of base node
        //require(child_type_lookup[node_id] == ltypes.Node);
        return TreeLib.getNode(getSection(getParent(node_id)),node_id);
    }

    function getNodesBatch(bytes32 index_id,bytes32 last_node_id) constant returns (bytes32[5][5] results) {
          TreeLib.Index storage index = indexes[index_id];

          //throw if empty
          require(index.size>0);

          if(last_node_id == 0x0)last_node_id = index.children[index.root].root;
          else last_node_id = index.children[getParent(last_node_id)].children[last_node_id].right;

          bytes32 section_id = getParent(last_node_id);
          TreeLib.Section storage sector = index.children[section_id];

          uint r = 0;

          while(r<5 && last_node_id!=0x0){
           results[0][r]= sector.children[last_node_id].id;
           results[1][r]= sector.children[last_node_id].left;
           results[2][r]= sector.children[last_node_id].right;
           results[3][r]= sector.children[last_node_id].parent;
           results[4][r]= sector.children[last_node_id].data;
           r++;

           if(sector.children[last_node_id].right == 0x0){
             if(sector.right != 0x0){
               sector = index.children[sector.right];
               last_node_id = sector.root;
               continue;
             }
           break;
           }
           else {
             last_node_id = sector.children[last_node_id].right;}
          }

          return results;
    }

    function removeSection(bytes32 index_id,bytes32 section_id) idNotEmpty(section_id){
      assert(getParent(section_id) == index_id);
      TreeLib.Index storage index = indexes[index_id];
      delete(parent_child_lookup[section_id]);
      TreeLib.removeSection(index,section_id);
    }

    function removeNode(bytes32 index_id,bytes32 node_id) idNotEmpty(node_id){
      bytes32 section_id = getParent(node_id);
      assert(getParent(section_id) == index_id);
      TreeLib.Section storage sector = getSection(section_id);

      delete(parent_child_lookup[node_id]);
      TreeLib.removeNode(sector,node_id);

      if(sector.size == 0)
      removeSection(index_id,section_id);
    }

    function generateSection() returns (bytes32 section_id){
      uint i = 0;
      while(childExists(sha3(block.difficulty+i,block.number+i,block.timestamp+1))){
        i++;
      }
      return sha3(block.difficulty+i,block.number+i,block.timestamp+1);
    }

    function newIndex(bytes32 index_id)idNotEmpty(index_id){
        indexes[index_id] = TreeLib.newIndex(index_id,parent_max_size);
    }

    function insertSection(bytes32 parent_id) returns(bytes32){
        //Create new index, if it does not exist
        if(!indexExists(parent_id))
          newIndex(parent_id);

        bytes32 section_id = generateSection();

        //Parent is an Index, store as child of index
        TreeLib.Index storage index = indexes[parent_id];
        parent_child_lookup[section_id] =  parent_id;
        TreeLib.insertSection(index,section_id);
        return section_id;
    }

    function insertNode(bytes32 index_id, bytes32 node_id, bytes32 data){
        //Ensure index and node are not empty
        require(index_id!= 0x0 && node_id != 0x0);

        //Create new index, if it does not exist
        if(!indexExists(index_id))
          newIndex(index_id);

        //check to see the next available sector
        bytes32 section_id = nextSection(index_id);
        if(section_id == 0x0)
          section_id = insertSection(index_id);

        parent_child_lookup[node_id] =  section_id;
        TreeLib.insertNode(getSection(section_id),node_id,data);
    }

    function insertNodeBatch(bytes32 index_id, bytes32[2][5] data){
      require(index_id!= 0x0);

      //Create new index, if it does not exist
      if(!indexExists(index_id))
        newIndex(index_id);

      //check to see the next available sector
      bytes32 section_id = nextSection(index_id);
      if(section_id == 0x0)
        section_id = insertSection(index_id);
      uint to_fill = indexes[index_id].children[section_id].maxsize - indexes[index_id].children[section_id].size;

      for(uint d=0;d<data.length;d++){
        bytes32 node_id = data[d][0];
        bytes32 node_data = data[d][1];
        //Ensure index and node are not empty
        if(node_id == 0x0)
        continue;

        //Generate new sector if exceeded
        if(to_fill < d+1){
          section_id = nextSection(index_id);
          if(section_id == 0x0)
            section_id = insertSection(index_id);
          to_fill += indexes[index_id].children[section_id].maxsize - indexes[index_id].children[section_id].size;
        }

        bytes32 right = 0x0;
        bytes32 left = 0x0;
        if(d==0){
          TreeLib.Section storage sector = getSection(section_id);
          left = sector.last;
          sector.children[left].right = node_id;
        }
        else{
          left = data[d-1][0];
        }
        if(data.length>d+1)
          right = data[d+1][0];

        parent_child_lookup[node_id] =  section_id;
        TreeLib.insertNodeBatch(getSection(section_id),left,right,node_id,node_data);
      }
    }

    modifier idNotEmpty(bytes32 id){
        require(id != 0x0);
        _;
    }

}


Change event details

Change event details

pragma solidity ^0.4.8;
import './InvitationRepository.sol';
import './ConfirmationRepository.sol';
import './zeppelin/ownership/Ownable.sol';
import './zeppelin/lifecycle/Destructible.sol';

contract Conference is Destructible {
	string public name;
	uint256 public totalBalance;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	uint public endedAt;
	uint public coolingPeriod;
	bool public invitation;
	bool public confirmation;
	InvitationRepository public invitationRepository;
	ConfirmationRepository public confirmationRepository;

	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;
	uint256 _payout;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		uint256 payout;
		bool paid;
	}

	event RegisterEvent(address addr, string participantName);
	event AttendEvent(address addr);
	event PaybackEvent(address addr, uint256 _payout);
	event WithdrawEvent(address addr, uint256 _payout);
	event CancelEvent(address addr, uint256 _payout);
	event ClearEvent(address addr, uint256 leftOver);

	/* Modifiers */
	modifier sentDepositOrReturn {
		if (msg.value == deposit) {
			_;
		}else{
			if(!msg.sender.send(msg.value)) throw;
		}
	}

	modifier onlyActive {
		if (ended == false) {
			_;
		}
	}

	modifier onlyActiveOrReturn {
		if (ended == false) {
			_;
		}else{
			if(!msg.sender.send(msg.value)) throw;
		}
	}

	modifier withinLimitOrReturn {
		if (registered < limitOfParticipants ) {
			_;
		}else{
			if(!msg.sender.send(msg.value)) throw;
		}
	}

	modifier isEnded {
		if (ended){
			_;
		}
	}

	modifier onlyAfter(uint _time) {
		if (now > _time){
			_;
		}
	}

	modifier onlyPayable {
		Participant participant = participants[msg.sender];
		if (participant.payout > 0){
			_;
		}
	}

	modifier notPaid {
		Participant participant = participants[msg.sender];
		if (participant.paid == false){
			_;
		}
	}

	modifier ifInvited(bytes32 invitation_code){
		if(invitation && !invitationRepository.claim(invitation_code, msg.sender)) throw;
		_;
	}

	modifier ifConfirmed(bytes32 _code){
		if(confirmation && !confirmationRepository.claim(_code, msg.sender)) throw;
		_;
	}

	/* Public functions */

	function Conference(uint _coolingPeriod, address _invitation_repository_address, address _confirmation_repository_address) {
		name = 'CodeUp #21';
		deposit = 0.05 ether;
		totalBalance = 0;
		registered = 0;
		attended = 0;
		limitOfParticipants = 20;
		ended = false;
		invitation = false;
		confirmation = false;
		if (_coolingPeriod != 0) {
			coolingPeriod = _coolingPeriod;
		} else {
			coolingPeriod = 1 weeks;
		}

		if (_invitation_repository_address !=0) {
			invitation = true;
			invitationRepository = InvitationRepository(_invitation_repository_address);
		}

		if (_confirmation_repository_address !=0) {
			confirmation = true;
			confirmationRepository = ConfirmationRepository(_confirmation_repository_address);
		}
	}

	function registerWithInvitation(string _participant, bytes32 _invitation_code) public sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn ifInvited(_invitation_code) payable{
		register(_participant);
	}

	function register(string _participant) public sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn payable{
		RegisterEvent(msg.sender, _participant);
		if (isRegistered(msg.sender)) throw;
		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, 0, false);
		totalBalance = totalBalance + (deposit * 1);
	}

	function attendWithConfirmation(bytes32 _confirmation) public ifConfirmed(_confirmation){
		if (isRegistered(msg.sender) != true) throw;
		if (isAttended(msg.sender)) throw;
		AttendEvent(msg.sender);
		participants[msg.sender].attended = true;
		attended++;
	}

	function withdraw() public onlyPayable notPaid {
		WithdrawEvent(msg.sender, participant.payout);
		Participant participant = participants[msg.sender];
		participant.paid = true;
		totalBalance -= participant.payout;
		if (!msg.sender.send(participant.payout)) {
			throw;
		}
	}

	/* Constants */
	function isRegistered(address _addr) constant returns (bool){
		return participants[_addr].addr != 0x0;
	}

	function isAttended(address _addr) constant returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function isPaid(address _addr) constant returns (bool){
		return isRegistered(_addr) && participants[_addr].paid;
	}

	function payout() constant returns(uint256){
		if (attended == 0) return 0;
		return uint(totalBalance) / uint(attended);
	}

	/* Admin only functions */

	function payback() onlyOwner{
		for(uint i=1;i<=registered;i++){
			if(participants[participantsIndex[i]].attended){
				participants[participantsIndex[i]].payout = payout();
				PaybackEvent(participantsIndex[i], payout());
			}
		}
		ended = true;
		endedAt = now;
	}

	function cancel() onlyOwner onlyActive{
		for(uint i=1;i<=registered;i++){
			participants[participantsIndex[i]].payout = deposit;
			CancelEvent(participantsIndex[i], deposit);
		}
		ended = true;
		endedAt = now;
	}

	/* return the remaining of balance if there are any unclaimed after cooling period */
	function clear() public onlyOwner isEnded onlyAfter(endedAt + coolingPeriod) {
		var leftOver = totalBalance;
		totalBalance = 0;
		ClearEvent(owner, leftOver);
		if(!owner.send(leftOver)) throw;
	}

	function setLimitOfParticipants(uint _limitOfParticipants) public onlyOwner{
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address[] _addresses) public onlyOwner{
		for(uint i=0;i<_addresses.length;i++){
			var _addr = _addresses[i];
			if (isRegistered(_addr) != true) throw;
			if (isAttended(_addr)) throw;
			AttendEvent(_addr);
			participants[_addr].attended = true;
			attended++;
		}
	}
}

pragma solidity ^0.4.8;
import './InvitationRepository.sol';
import './ConfirmationRepository.sol';
import './zeppelin/ownership/Ownable.sol';
import './zeppelin/lifecycle/Destructible.sol';

contract Conference is Destructible {
	string public name;
	uint256 public totalBalance;
	uint256 public deposit;
	uint public limitOfParticipants;
	uint public registered;
	uint public attended;
	bool public ended;
	uint public endedAt;
	uint public coolingPeriod;
	bool public invitation;
	bool public confirmation;
	InvitationRepository public invitationRepository;
	ConfirmationRepository public confirmationRepository;

	mapping (address => Participant) public participants;
	mapping (uint => address) public participantsIndex;
	bool paid;
	uint256 _payout;

	struct Participant {
		string participantName;
		address addr;
		bool attended;
		uint256 payout;
		bool paid;
	}

	event RegisterEvent(address addr, string participantName);
	event AttendEvent(address addr);
	event PaybackEvent(address addr, uint256 _payout);
	event WithdrawEvent(address addr, uint256 _payout);
	event CancelEvent(address addr, uint256 _payout);
	event ClearEvent(address addr, uint256 leftOver);

	/* Modifiers */
	modifier sentDepositOrReturn {
		if (msg.value == deposit) {
			_;
		}else{
			if(!msg.sender.send(msg.value)) throw;
		}
	}

	modifier onlyActive {
		if (ended == false) {
			_;
		}
	}

	modifier onlyActiveOrReturn {
		if (ended == false) {
			_;
		}else{
			if(!msg.sender.send(msg.value)) throw;
		}
	}

	modifier withinLimitOrReturn {
		if (registered < limitOfParticipants ) {
			_;
		}else{
			if(!msg.sender.send(msg.value)) throw;
		}
	}

	modifier isEnded {
		if (ended){
			_;
		}
	}

	modifier onlyAfter(uint _time) {
		if (now > _time){
			_;
		}
	}

	modifier onlyPayable {
		Participant participant = participants[msg.sender];
		if (participant.payout > 0){
			_;
		}
	}

	modifier notPaid {
		Participant participant = participants[msg.sender];
		if (participant.paid == false){
			_;
		}
	}

	modifier ifInvited(bytes32 invitation_code){
		if(invitation && !invitationRepository.claim(invitation_code, msg.sender)) throw;
		_;
	}

	modifier ifConfirmed(bytes32 _code){
		if(confirmation && !confirmationRepository.claim(_code, msg.sender)) throw;
		_;
	}

	/* Public functions */

	function Conference(uint _coolingPeriod, address _invitation_repository_address, address _confirmation_repository_address) {
		name = 'Test';
		deposit = 0.1 ether;
		totalBalance = 0;
		registered = 0;
		attended = 0;
		limitOfParticipants = 10;
		ended = false;
		invitation = false;
		confirmation = false;
		if (_coolingPeriod != 0) {
			coolingPeriod = _coolingPeriod;
		} else {
			coolingPeriod = 1 weeks;
		}

		if (_invitation_repository_address !=0) {
			invitation = true;
			invitationRepository = InvitationRepository(_invitation_repository_address);
		}

		if (_confirmation_repository_address !=0) {
			confirmation = true;
			confirmationRepository = ConfirmationRepository(_confirmation_repository_address);
		}
	}

	function registerWithInvitation(string _participant, bytes32 _invitation_code) public sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn ifInvited(_invitation_code) payable{
		register(_participant);
	}

	function register(string _participant) public sentDepositOrReturn withinLimitOrReturn onlyActiveOrReturn payable{
		RegisterEvent(msg.sender, _participant);
		if (isRegistered(msg.sender)) throw;
		registered++;
		participantsIndex[registered] = msg.sender;
		participants[msg.sender] = Participant(_participant, msg.sender, false, 0, false);
		totalBalance = totalBalance + (deposit * 1);
	}

	function attendWithConfirmation(bytes32 _confirmation) public ifConfirmed(_confirmation){
		if (isRegistered(msg.sender) != true) throw;
		if (isAttended(msg.sender)) throw;
		AttendEvent(msg.sender);
		participants[msg.sender].attended = true;
		attended++;
	}

	function withdraw() public onlyPayable notPaid {
		WithdrawEvent(msg.sender, participant.payout);
		Participant participant = participants[msg.sender];
		participant.paid = true;
		totalBalance -= participant.payout;
		if (!msg.sender.send(participant.payout)) {
			throw;
		}
	}

	/* Constants */
	function isRegistered(address _addr) constant returns (bool){
		return participants[_addr].addr != 0x0;
	}

	function isAttended(address _addr) constant returns (bool){
		return isRegistered(_addr) && participants[_addr].attended;
	}

	function isPaid(address _addr) constant returns (bool){
		return isRegistered(_addr) && participants[_addr].paid;
	}

	function payout() constant returns(uint256){
		if (attended == 0) return 0;
		return uint(totalBalance) / uint(attended);
	}

	/* Admin only functions */

	function payback() onlyOwner{
		for(uint i=1;i<=registered;i++){
			if(participants[participantsIndex[i]].attended){
				participants[participantsIndex[i]].payout = payout();
				PaybackEvent(participantsIndex[i], payout());
			}
		}
		ended = true;
		endedAt = now;
	}

	function cancel() onlyOwner onlyActive{
		for(uint i=1;i<=registered;i++){
			participants[participantsIndex[i]].payout = deposit;
			CancelEvent(participantsIndex[i], deposit);
		}
		ended = true;
		endedAt = now;
	}

	/* return the remaining of balance if there are any unclaimed after cooling period */
	function clear() public onlyOwner isEnded onlyAfter(endedAt + coolingPeriod) {
		var leftOver = totalBalance;
		totalBalance = 0;
		ClearEvent(owner, leftOver);
		if(!owner.send(leftOver)) throw;
	}

	function setLimitOfParticipants(uint _limitOfParticipants) public onlyOwner{
		limitOfParticipants = _limitOfParticipants;
	}

	function attend(address[] _addresses) public onlyOwner{
		for(uint i=0;i<_addresses.length;i++){
			var _addr = _addresses[i];
			if (isRegistered(_addr) != true) throw;
			if (isAttended(_addr)) throw;
			AttendEvent(_addr);
			participants[_addr].attended = true;
			attended++;
		}
	}
}