Refactored to SafeMath.

Refactored to SafeMath.

pragma solidity ^0.4.15;

import './SafeMath.sol';
import './Ownable.sol';
import './TokenHolder.sol';
import './KinToken.sol';
import './VestingTrustee.sol';

/// @title Kin token sale contract.
contract KinTokenSale is Ownable, TokenHolder {
    using SafeMath for uint256;

    // External parties:

    // KIN token contract.
    KinToken public kin;

    // Vesting contract for pre-sale participants.
    VestingTrustee public trustee;

    // Received funds are forwarded to this address.
    address public fundingRecipient;

    // Kin token unit.
    // Using same decimal value as ETH (makes ETH-KIN conversion much easier).
    // This is the same as in Kin token contract.
    uint256 public constant TOKEN_UNIT = 10 ** 18;

    // Maximum number of tokens in circulation: 10 trillion.
    uint256 public constant MAX_TOKENS = 10 ** 13 * TOKEN_UNIT;

    // Maximum tokens offered in the sale.
    uint256 public constant MAX_TOKENS_SOLD = 512192121951 * TOKEN_UNIT;

    // Wei to 1 USD ratio.
    //
    // TODO update to the real ETH price before sale launch.
    uint256 public constant WEI_PER_USD = uint256(1 ether) / 360;

    // KIN to 1 USD ratio,
    // such MAX_TOKENS_SOLD * KIN_PER_USD is the $75M cap.
    uint256 public constant KIN_PER_USD = 6829 * TOKEN_UNIT;

    // KIN to 1 wei ratio.
    uint256 public constant KIN_PER_WEI = KIN_PER_USD / WEI_PER_USD;

    // Sale start and end time.
    uint256 public constant SALE_DURATION = 14 days;
    uint256 public startTime;
    uint256 public endTime;

    // Amount of tokens sold until now in the sale.
    uint256 public tokensSold = 0;

    // Participation caps, according to KYC tiers.
    uint256 public constant TIER_1_CAP = 100000 * WEI_PER_USD;
    uint256 public constant TIER_2_CAP = uint256(-1); // Maximum uint256 value

    // Accumulated amount each participant have contributed so far.
    mapping (address => uint256) public participationHistory;

    // Maximum amount that each particular is allowed to contribute (in WEI).
    mapping (address => uint256) public participationCaps;

    // Maximum amount ANYBODY is currently allowed to contribute.
    uint256 public hardParticipationCap = 5000 * WEI_PER_USD;

    // Vesting information for special addresses:
    struct TokenGrant {
        uint256 value;
        uint256 startOffset;
        uint256 cliffOffset;
        uint256 endOffset;
        uint256 installmentLength;
        uint8 percentVested;
    }

    address[] public tokenGrantees;
    mapping (address => TokenGrant) public tokenGrants;
    uint256 public lastGrantedIndex = 0;
    uint256 public constant MAX_TOKEN_GRANTEES = 100;
    uint256 public constant GRANT_BATCH_SIZE = 10;

    // Post-TDE multisig addresses.
    //
    // TODO: add real addresses here.
    address public constant KIN_FOUNDATION_ADDRESS = 0xa8F769B88d6D74FB2Bd3912F6793F75625228baF;
    address public constant KIK_ADDRESS = 0x7a029DC995f87B5cA060975b9A8A1b4bdB33cDC5;

    event TokensIssued(address indexed _to, uint256 _tokens);

    /// @dev Reverts if called when not during sale.
    modifier onlyDuringSale() {
        require(!saleEnded() && now >= startTime);

        _;
    }

    /// @dev Reverts if called before sale ends.
    modifier onlyAfterSale() {
        require(saleEnded());

        _;
    }

    /// @dev Constructor that initializes the sale conditions.
    /// @param _fundingRecipient address The address of the funding recipient.
    /// @param _startTime uint256 The start time of the token sale.
    function KinTokenSale(address _fundingRecipient, uint256 _startTime) {
        require(_fundingRecipient != address(0));
        require(_startTime > now);

        // Deploy new KinToken contract.
        kin = new KinToken();

        // Deploy new VestingTrustee contract.
        trustee = new VestingTrustee(kin);

        fundingRecipient = _fundingRecipient;
        startTime = _startTime;
        endTime = startTime + SALE_DURATION;

        // Initialize special vesting grants.
        initTokenGrants();
    }

    /// @dev Initialize token grants.
    ///
    /// TODO: add real values here.
    function initTokenGrants() private onlyOwner {
        // Issue the remaining 60% to Kin Foundation's multisig wallet. In a few days, after the token sale is
        // finalized, these tokens will be loaded into the KinVestingTrustee smart contract, according to the white
        // paper. Please note, that this is implied by setting a 0% vesting percent.
        tokenGrantees.push(KIN_FOUNDATION_ADDRESS);
        tokenGrants[KIN_FOUNDATION_ADDRESS] = TokenGrant(MAX_TOKENS.mul(60).div(100), 0, 0, 3 years, 1 days, 0);

        // Kik, 30%
        tokenGrantees.push(KIK_ADDRESS);
        tokenGrants[KIK_ADDRESS] = TokenGrant(MAX_TOKENS.mul(30).div(100), 0, 0, 120 weeks, 12 weeks, 100);
    }

    /// @dev Adds a Kin token vesting grant.
    /// @param _grantee address The address of the token grantee. Can be granted only once.
    /// @param _value uint256 The value of the grant.
    function addTokenGrant(address _grantee, uint256 _value) external onlyOwner {
        require(_grantee != address(0));
        require(_value > 0);
        require(tokenGrantees.length + 1 <= MAX_TOKEN_GRANTEES);

        // Verify the grant doesn't already exist.
        require(tokenGrants[_grantee].value == 0);
        for (uint i = 0; i < tokenGrantees.length; i++) {
            require(tokenGrantees[i] != _grantee);
        }

        // Add grant and add to grantee list.
        tokenGrantees.push(_grantee);
        tokenGrants[_grantee] = TokenGrant(_value, 0, 1 years, 1 years, 1 days, 50);
    }

    /// @dev Deletes a Kin token grant.
    /// @param _grantee address The address of the token grantee.
    function deleteTokenGrant(address _grantee) external onlyOwner {
        require(_grantee != address(0));

        // Delete the grant from the keys array.
        for (uint i = 0; i < tokenGrantees.length; i++) {
            if (tokenGrantees[i] == _grantee) {
                delete tokenGrantees[i];

                break;
            }
        }

        // Delete the grant from the mapping.
        delete tokenGrants[_grantee];
    }

    /// @dev Add a list of participants to a capped participation tier.
    /// @param _participants address[] The list of participant addresses.
    /// @param _cap uint256 The cap amount (in ETH).
    function setParticipationCap(address[] _participants, uint256 _cap) private onlyOwner {
        for (uint i = 0; i < _participants.length; i++) {
            participationCaps[_participants[i]] = _cap;
        }
    }

    /// @dev Add a list of participants to cap tier #1.
    /// @param _participants address[] The list of participant addresses.
    function setTier1Participants(address[] _participants) external onlyOwner {
        setParticipationCap(_participants, TIER_1_CAP);
    }

    /// @dev Add a list of participants to tier #2.
    /// @param _participants address[] The list of participant addresses.
    function setTier2Participants(address[] _participants) external onlyOwner {
        setParticipationCap(_participants, TIER_2_CAP);
    }

    /// @dev Set hard participation cap for all participants.
    /// @param _cap uint256 The hard cap amount.
    function setHardParticipationCap(uint256 _cap) external onlyOwner {
        require(_cap > 0);

        hardParticipationCap = _cap;
    }

    /// @dev Fallback function that will delegate the request to create().
    function () external payable onlyDuringSale {
        create(msg.sender);
    }

    /// @dev Create and sell tokens to the caller.
    /// @param _recipient address The address of the recipient receiving the tokens.
    function create(address _recipient) public payable onlyDuringSale {
        require(_recipient != address(0));

        // Enforce participation cap (in Wei received).
        uint256 weiAlreadyParticipated = participationHistory[msg.sender];
        uint256 participationCap = SafeMath.min256(participationCaps[msg.sender], hardParticipationCap);
        uint256 cappedWeiReceived = SafeMath.min256(msg.value, participationCap.sub(weiAlreadyParticipated));
        require(cappedWeiReceived > 0);

        // Accept funds and transfer to funding recipient.
        uint256 weiLeftInSale = MAX_TOKENS_SOLD.sub(tokensSold).div(KIN_PER_WEI);
        uint256 weiToParticipate = SafeMath.min256(cappedWeiReceived, weiLeftInSale);
        participationHistory[msg.sender] = weiAlreadyParticipated.add(weiToParticipate);
        fundingRecipient.transfer(weiToParticipate);

        // Issue tokens and transfer to recipient.
        uint256 tokensLeftInSale = MAX_TOKENS_SOLD.sub(tokensSold);
        uint256 tokensToIssue = weiToParticipate.mul(KIN_PER_WEI);
        if (tokensLeftInSale.sub(tokensToIssue) < KIN_PER_WEI) {
            // If purchase would cause less than KIN_PER_WEI tokens left then nobody could ever buy them.
            // So, gift them to the last buyer.
            tokensToIssue = tokensLeftInSale;
        }
        tokensSold = tokensSold.add(tokensToIssue);
        issueTokens(_recipient, tokensToIssue);

        // Partial refund if full participation not possible
        // e.g. due to cap being reached.
        uint256 refund = msg.value.sub(weiToParticipate);
        if (refund > 0) {
            msg.sender.transfer(refund);
        }
    }

    /// @dev Finalizes the token sale event, by stopping token minting.
    function finalize() external onlyAfterSale onlyOwner {
        if (!kin.isMinting()) {
            revert();
        }

        require(lastGrantedIndex == tokenGrantees.length);

        // Finish minting.
        kin.endMinting();
    }

    /// @dev Grants pre-configured token grants in batches. When the method is called, it'll resume from the last grant,
    /// from its previous run, and will finish either after granting GRANT_BATCH_SIZE grants or finishing the whole list
    /// of grants.
    function grantTokens() external onlyAfterSale onlyOwner {
        uint endIndex = SafeMath.min256(tokenGrantees.length, lastGrantedIndex + GRANT_BATCH_SIZE);
        for (uint i = lastGrantedIndex; i < endIndex; i++) {
            address grantee = tokenGrantees[i];

            // Calculate how many tokens have been granted, vested, and issued such that: granted = vested + issued.
            TokenGrant memory tokenGrant = tokenGrants[grantee];
            uint256 tokensGranted = tokenGrant.value.mul(tokensSold).div(MAX_TOKENS_SOLD);
            uint256 tokensVesting = tokensGranted.mul(tokenGrant.percentVested).div(100);
            uint256 tokensIssued = tokensGranted.sub(tokensVesting);

            // Transfer issued tokens that have yet to be transferred to grantee.
            if (tokensIssued > 0) {
                issueTokens(grantee, tokensIssued);
            }

            // Transfer vested tokens that have yet to be transferred to vesting trustee, and initialize grant.
            if (tokensVesting > 0) {
                issueTokens(trustee, tokensVesting);
                trustee.grant(grantee, tokensVesting, now.add(tokenGrant.startOffset), now.add(tokenGrant.cliffOffset),
                    now.add(tokenGrant.endOffset), tokenGrant.installmentLength, true);
            }

            lastGrantedIndex++;
        }
    }

    /// @dev Issues tokens for the recipient.
    /// @param _recipient address The address of the recipient.
    /// @param _tokens uint256 The amount of tokens to issue.
    function issueTokens(address _recipient, uint256 _tokens) private {
        // Request Kin token contract to mint the requested tokens for the buyer.
        kin.mint(_recipient, _tokens);

        TokensIssued(_recipient, _tokens);
    }

    /// @dev Returns whether the sale has ended.
    /// @return bool Whether the sale has ended or not.
    function saleEnded() private constant returns (bool) {
        return tokensSold >= MAX_TOKENS_SOLD || now >= endTime;
    }

    /// @dev Requests to transfer control of the Kin token contract to a new owner.
    /// @param _newOwnerCandidate address The address to transfer ownership to.
    ///
    /// NOTE:
    ///   1. The new owner will need to call Kin token contract's acceptOwnership directly in order to accept the ownership.
    ///   2. Calling this method during the token sale will prevent the token sale to continue, since only the owner of
    ///      the Kin token contract can issue new tokens.
    function requestKinTokenOwnershipTransfer(address _newOwnerCandidate) external onlyOwner {
        kin.requestOwnershipTransfer(_newOwnerCandidate);
    }

    /// @dev Accepts new ownership on behalf of the Kin token contract.
    // This can be used by the sale contract itself to claim back ownership of the Kin token contract.
    function acceptKinTokenOwnership() external onlyOwner {
        kin.acceptOwnership();
    }

    /// @dev Requests to transfer control of the VestingTrustee contract to a new owner.
    /// @param _newOwnerCandidate address The address to transfer ownership to.
    ///
    /// NOTE:
    ///   1. The new owner will need to call VestingTrustee's acceptOwnership directly in order to accept the ownership.
    ///   2. Calling this method during the token sale will prevent the token sale from finalizaing, since only the owner
    ///      of the VestingTrustee contract can issue new token grants.
    function requestVestingTrusteeOwnershipTransfer(address _newOwnerCandidate) external onlyOwner {
        trustee.requestOwnershipTransfer(_newOwnerCandidate);
    }

    /// @dev Accepts new ownership on behalf of the VestingTrustee contract.
    /// This can be used by the token sale contract itself to claim back ownership of the VestingTrustee contract.
    function acceptVestingTrusteeOwnership() external onlyOwner {
        trustee.acceptOwnership();
    }
}

pragma solidity ^0.4.15;

import './SafeMath.sol';
import './Ownable.sol';
import './TokenHolder.sol';
import './KinToken.sol';
import './VestingTrustee.sol';

/// @title Kin token sale contract.
contract KinTokenSale is Ownable, TokenHolder {
    using SafeMath for uint256;

    // External parties:

    // KIN token contract.
    KinToken public kin;

    // Vesting contract for pre-sale participants.
    VestingTrustee public trustee;

    // Received funds are forwarded to this address.
    address public fundingRecipient;

    // Kin token unit.
    // Using same decimal value as ETH (makes ETH-KIN conversion much easier).
    // This is the same as in Kin token contract.
    uint256 public constant TOKEN_UNIT = 10 ** 18;

    // Maximum number of tokens in circulation: 10 trillion.
    uint256 public constant MAX_TOKENS = 10 ** 13 * TOKEN_UNIT;

    // Maximum tokens offered in the sale.
    uint256 public constant MAX_TOKENS_SOLD = 512192121951 * TOKEN_UNIT;

    // Wei to 1 USD ratio.
    //
    // TODO update to the real ETH price before sale launch.
    uint256 public constant WEI_PER_USD = uint256(1 ether) / 360;

    // KIN to 1 USD ratio,
    // such MAX_TOKENS_SOLD * KIN_PER_USD is the $75M cap.
    uint256 public constant KIN_PER_USD = 6829 * TOKEN_UNIT;

    // KIN to 1 wei ratio.
    uint256 public constant KIN_PER_WEI = KIN_PER_USD / WEI_PER_USD;

    // Sale start and end time.
    uint256 public constant SALE_DURATION = 14 days;
    uint256 public startTime;
    uint256 public endTime;

    // Amount of tokens sold until now in the sale.
    uint256 public tokensSold = 0;

    // Participation caps, according to KYC tiers.
    uint256 public constant TIER_1_CAP = 100000 * WEI_PER_USD;
    uint256 public constant TIER_2_CAP = uint256(-1); // Maximum uint256 value

    // Accumulated amount each participant have contributed so far.
    mapping (address => uint256) public participationHistory;

    // Maximum amount that each particular is allowed to contribute (in WEI).
    mapping (address => uint256) public participationCaps;

    // Maximum amount ANYBODY is currently allowed to contribute.
    uint256 public hardParticipationCap = 5000 * WEI_PER_USD;

    // Vesting information for special addresses:
    struct TokenGrant {
        uint256 value;
        uint256 startOffset;
        uint256 cliffOffset;
        uint256 endOffset;
        uint256 installmentLength;
        uint8 percentVested;
    }

    address[] public tokenGrantees;
    mapping (address => TokenGrant) public tokenGrants;
    uint256 public lastGrantedIndex = 0;
    uint256 public constant MAX_TOKEN_GRANTEES = 100;
    uint256 public constant GRANT_BATCH_SIZE = 10;

    // Post-TDE multisig addresses.
    //
    // TODO: add real addresses here.
    address public constant KIN_FOUNDATION_ADDRESS = 0xa8F769B88d6D74FB2Bd3912F6793F75625228baF;
    address public constant KIK_ADDRESS = 0x7a029DC995f87B5cA060975b9A8A1b4bdB33cDC5;

    event TokensIssued(address indexed _to, uint256 _tokens);

    /// @dev Reverts if called when not during sale.
    modifier onlyDuringSale() {
        require(!saleEnded() && now >= startTime);

        _;
    }

    /// @dev Reverts if called before sale ends.
    modifier onlyAfterSale() {
        require(saleEnded());

        _;
    }

    /// @dev Constructor that initializes the sale conditions.
    /// @param _fundingRecipient address The address of the funding recipient.
    /// @param _startTime uint256 The start time of the token sale.
    function KinTokenSale(address _fundingRecipient, uint256 _startTime) {
        require(_fundingRecipient != address(0));
        require(_startTime > now);

        // Deploy new KinToken contract.
        kin = new KinToken();

        // Deploy new VestingTrustee contract.
        trustee = new VestingTrustee(kin);

        fundingRecipient = _fundingRecipient;
        startTime = _startTime;
        endTime = startTime + SALE_DURATION;

        // Initialize special vesting grants.
        initTokenGrants();
    }

    /// @dev Initialize token grants.
    ///
    /// TODO: add real values here.
    function initTokenGrants() private onlyOwner {
        // Issue the remaining 60% to Kin Foundation's multisig wallet. In a few days, after the token sale is
        // finalized, these tokens will be loaded into the KinVestingTrustee smart contract, according to the white
        // paper. Please note, that this is implied by setting a 0% vesting percent.
        tokenGrantees.push(KIN_FOUNDATION_ADDRESS);
        tokenGrants[KIN_FOUNDATION_ADDRESS] = TokenGrant(60 * MAX_TOKENS.div(100), 0, 0, 3 years, 1 days, 0);

        // Kik, 30%
        tokenGrantees.push(KIK_ADDRESS);
        tokenGrants[KIK_ADDRESS] = TokenGrant(30 * MAX_TOKENS.div(100), 0, 0, 120 weeks, 12 weeks, 100);
    }

    /// @dev Adds a Kin token vesting grant.
    /// @param _grantee address The address of the token grantee. Can be granted only once.
    /// @param _value uint256 The value of the grant.
    function addTokenGrant(address _grantee, uint256 _value) external onlyOwner {
        require(_grantee != address(0));
        require(_value > 0);
        require(tokenGrantees.length + 1 <= MAX_TOKEN_GRANTEES);

        // Verify the grant doesn't already exist.
        require(tokenGrants[_grantee].value == 0);
        for (uint i = 0; i < tokenGrantees.length; i++) {
            require(tokenGrantees[i] != _grantee);
        }

        // Add grant and add to grantee list.
        tokenGrantees.push(_grantee);
        tokenGrants[_grantee] = TokenGrant(_value, 0, 1 years, 1 years, 1 days, 50);
    }

    /// @dev Deletes a Kin token grant.
    /// @param _grantee address The address of the token grantee.
    function deleteTokenGrant(address _grantee) external onlyOwner {
        require(_grantee != address(0));

        // Delete the grant from the keys array.
        for (uint i = 0; i < tokenGrantees.length; i++) {
            if (tokenGrantees[i] == _grantee) {
                delete tokenGrantees[i];

                break;
            }
        }

        // Delete the grant from the mapping.
        delete tokenGrants[_grantee];
    }

    /// @dev Add a list of participants to a capped participation tier.
    /// @param _participants address[] The list of participant addresses.
    /// @param _cap uint256 The cap amount (in ETH).
    function setParticipationCap(address[] _participants, uint256 _cap) private onlyOwner {
        for (uint i = 0; i < _participants.length; i++) {
            participationCaps[_participants[i]] = _cap;
        }
    }

    /// @dev Add a list of participants to cap tier #1.
    /// @param _participants address[] The list of participant addresses.
    function setTier1Participants(address[] _participants) external onlyOwner {
        setParticipationCap(_participants, TIER_1_CAP);
    }

    /// @dev Add a list of participants to tier #2.
    /// @param _participants address[] The list of participant addresses.
    function setTier2Participants(address[] _participants) external onlyOwner {
        setParticipationCap(_participants, TIER_2_CAP);
    }

    /// @dev Set hard participation cap for all participants.
    /// @param _cap uint256 The hard cap amount.
    function setHardParticipationCap(uint256 _cap) external onlyOwner {
        require(_cap > 0);

        hardParticipationCap = _cap;
    }

    /// @dev Fallback function that will delegate the request to create().
    function () external payable onlyDuringSale {
        create(msg.sender);
    }

    /// @dev Create and sell tokens to the caller.
    /// @param _recipient address The address of the recipient receiving the tokens.
    function create(address _recipient) public payable onlyDuringSale {
        require(_recipient != address(0));

        // Enforce participation cap (in Wei received).
        uint256 weiAlreadyParticipated = participationHistory[msg.sender];
        uint256 participationCap = SafeMath.min256(participationCaps[msg.sender], hardParticipationCap);
        uint256 cappedWeiReceived = SafeMath.min256(msg.value, participationCap.sub(weiAlreadyParticipated));
        require(cappedWeiReceived > 0);

        // Accept funds and transfer to funding recipient.
        uint256 weiLeftInSale = MAX_TOKENS_SOLD.sub(tokensSold).div(KIN_PER_WEI);
        uint256 weiToParticipate = SafeMath.min256(cappedWeiReceived, weiLeftInSale);
        participationHistory[msg.sender] = weiAlreadyParticipated.add(weiToParticipate);
        fundingRecipient.transfer(weiToParticipate);

        // Issue tokens and transfer to recipient.
        uint256 tokensLeftInSale = MAX_TOKENS_SOLD.sub(tokensSold);
        uint256 tokensToIssue = weiToParticipate.mul(KIN_PER_WEI);
        if (tokensLeftInSale.sub(tokensToIssue) < KIN_PER_WEI) {
            // If purchase would cause less than KIN_PER_WEI tokens left then nobody could ever buy them.
            // So, gift them to the last buyer.
            tokensToIssue = tokensLeftInSale;
        }
        tokensSold = tokensSold.add(tokensToIssue);
        issueTokens(_recipient, tokensToIssue);

        // Partial refund if full participation not possible
        // e.g. due to cap being reached.
        uint256 refund = msg.value.sub(weiToParticipate);
        if (refund > 0) {
            msg.sender.transfer(refund);
        }
    }

    /// @dev Finalizes the token sale event, by stopping token minting.
    function finalize() external onlyAfterSale onlyOwner {
        if (!kin.isMinting()) {
            revert();
        }

        require(lastGrantedIndex == tokenGrantees.length);

        // Finish minting.
        kin.endMinting();
    }

    /// @dev Grants pre-configured token grants in batches. When the method is called, it'll resume from the last grant,
    /// from its previous run, and will finish either after granting GRANT_BATCH_SIZE grants or finishing the whole list
    /// of grants.
    function grantTokens() external onlyAfterSale onlyOwner {
        uint endIndex = SafeMath.min256(tokenGrantees.length, lastGrantedIndex + GRANT_BATCH_SIZE);
        for (uint i = lastGrantedIndex; i < endIndex; i++) {
            address grantee = tokenGrantees[i];

            // Calculate how many tokens have been granted, vested, and issued such that: granted = vested + issued.
            TokenGrant memory tokenGrant = tokenGrants[grantee];
            uint256 tokensGranted = tokenGrant.value.mul(tokensSold).div(MAX_TOKENS_SOLD);
            uint256 tokensVesting = tokensGranted.mul(tokenGrant.percentVested).div(100);
            uint256 tokensIssued = tokensGranted.sub(tokensVesting);

            // Transfer issued tokens that have yet to be transferred to grantee.
            if (tokensIssued > 0) {
                issueTokens(grantee, tokensIssued);
            }

            // Transfer vested tokens that have yet to be transferred to vesting trustee, and initialize grant.
            if (tokensVesting > 0) {
                issueTokens(trustee, tokensVesting);
                trustee.grant(grantee, tokensVesting, now.add(tokenGrant.startOffset), now.add(tokenGrant.cliffOffset),
                    now.add(tokenGrant.endOffset), tokenGrant.installmentLength, true);
            }

            lastGrantedIndex++;
        }
    }

    /// @dev Issues tokens for the recipient.
    /// @param _recipient address The address of the recipient.
    /// @param _tokens uint256 The amount of tokens to issue.
    function issueTokens(address _recipient, uint256 _tokens) private {
        // Request Kin token contract to mint the requested tokens for the buyer.
        kin.mint(_recipient, _tokens);

        TokensIssued(_recipient, _tokens);
    }

    /// @dev Returns whether the sale has ended.
    /// @return bool Whether the sale has ended or not.
    function saleEnded() private constant returns (bool) {
        return tokensSold >= MAX_TOKENS_SOLD || now >= endTime;
    }

    /// @dev Requests to transfer control of the Kin token contract to a new owner.
    /// @param _newOwnerCandidate address The address to transfer ownership to.
    ///
    /// NOTE:
    ///   1. The new owner will need to call Kin token contract's acceptOwnership directly in order to accept the ownership.
    ///   2. Calling this method during the token sale will prevent the token sale to continue, since only the owner of
    ///      the Kin token contract can issue new tokens.
    function requestKinTokenOwnershipTransfer(address _newOwnerCandidate) external onlyOwner {
        kin.requestOwnershipTransfer(_newOwnerCandidate);
    }

    /// @dev Accepts new ownership on behalf of the Kin token contract.
    // This can be used by the sale contract itself to claim back ownership of the Kin token contract.
    function acceptKinTokenOwnership() external onlyOwner {
        kin.acceptOwnership();
    }

    /// @dev Requests to transfer control of the VestingTrustee contract to a new owner.
    /// @param _newOwnerCandidate address The address to transfer ownership to.
    ///
    /// NOTE:
    ///   1. The new owner will need to call VestingTrustee's acceptOwnership directly in order to accept the ownership.
    ///   2. Calling this method during the token sale will prevent the token sale from finalizaing, since only the owner
    ///      of the VestingTrustee contract can issue new token grants.
    function requestVestingTrusteeOwnershipTransfer(address _newOwnerCandidate) external onlyOwner {
        trustee.requestOwnershipTransfer(_newOwnerCandidate);
    }

    /// @dev Accepts new ownership on behalf of the VestingTrustee contract.
    /// This can be used by the token sale contract itself to claim back ownership of the VestingTrustee contract.
    function acceptVestingTrusteeOwnership() external onlyOwner {
        trustee.acceptOwnership();
    }
}


Use correct token identifier.

Use correct token identifier.

Signed-off-by: Nikita <5c9993fe5c1b9bfc216420fea06629aef1fdc9c2@gmail.com>

pragma solidity ^0.4.17;

import "./StandardToken.sol";

/**
 * @title The Pre-Leo Token contract.
 *
 * Credit: Taking ideas from BAT token and NET token
 */
contract PLToken is StandardToken {

    // Token metadata
    string public constant name = "Pre-Leo Token";
    string public constant symbol = "PLT";
    uint256 public constant decimals = 18;
    string public version = "0.9";

    // Fundraising parameters
    enum ContractState { Fundraising, Finalized, Redeeming, Paused }
    ContractState public state;           // Current state of the contract
    ContractState private savedState;     // State of the contract before pause

    uint256 public fundingStartBlock;        // These two blocks need to be chosen to comply with the
    uint256 public fundingEndBlock;          // start date and 28 day duration requirements
    uint256 public exchangeRateChangesBlock; // block number that triggers the exchange rate change

    address public admin1; // First administrator for multi-sig mechanism
    address public admin2; // Second administrator for multi-sig mechanism

    uint256 public constant TOKEN_FIRST_EXCHANGE_RATE = 200; // 200 PLTs per 1 ETH
    uint256 public constant TOKEN_SECOND_EXCHANGE_RATE = 175; // 175 PLTs per 1 ETH
    uint256 public constant TOKEN_CREATION_CAP = 10 * (10**6) * 10**decimals; // 10 million PLTs
    uint256 public constant ETH_RECEIVED_CAP = 50 * (10**3) * 10**decimals; // 50 000 ETH
    uint256 public constant ETH_RECEIVED_MIN = 10 * (10**3) * 10**decimals; // 10 000 ETH
    uint256 public constant TOKEN_MIN = 1 * 10**decimals; // 1 PLT

    // We need to keep track of how much ether have been contributed, since we have a cap for ETH too
    uint256 public totalReceivedEth = 0;

    // Since we have different exchange rates at different stages, we need to keep track
    // of how much ether each contributed in case that we need to issue a refund
    mapping (address => uint256) private ethBalances;
    mapping (address => bytes32) private multiSigHashes; // store the hashes of admins' msg.data

    // Events used for logging
    event LogRefund(address indexed _to, uint256 _value);
    event LogCreatePLT(address indexed _to, uint256 _value);
    event LogRedeemPLT(address indexed _from, uint256 _value, string _leoAddress);

    modifier isFinalized() {
        require(state == ContractState.Finalized);
        _;
    }

    modifier isFundraising() {
        require(state == ContractState.Fundraising);
        _;
    }

    modifier isRedeeming() {
        require(state == ContractState.Redeeming);
        _;
    }

    modifier isPaused() {
        require(state == ContractState.Paused);
        _;
    }

    modifier notPaused() {
        require(state != ContractState.Paused);
        _;
    }

    modifier isFundraisingIgnorePaused() {
        require(state == ContractState.Fundraising || (state == ContractState.Paused && savedState == ContractState.Fundraising));
        _;
    }

    modifier onlyOwner() {
        // check if transaction sender is admin.
        require (msg.sender == admin1 || msg.sender == admin2);
        // if yes, store his msg.data.
        multiSigHashes[msg.sender] = keccak256(msg.data);
        // check if his stored msg.data hash equals to the one of the other admin
        if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) {
            // if yes, both admins agreed - continue.
            _;
        } else {
            // if not (yet), return.
            return;
        }
    }

    modifier minimumReached() {
        require(totalReceivedEth >= ETH_RECEIVED_MIN);
        _;
    }

    /**
     * @dev Create a new PLToken contract.
     *
     * @param _fundingStartBlock The starting block of the fundraiser (has to be in the future).
     * @param _fundingEndBlock The end block of the fundraiser (has to be after _fundingStartBlock).
     * @param _exchangeRateChangesBlock The block that changes the exchange rate (has to be between _fundingStartBlock and _fundingEndBlock).
     * @param _admin1 The first admin account that owns this contract.
     * @param _admin2 The second admin account that owns this contract.
     */
    function PLToken(
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock,
        uint256 _exchangeRateChangesBlock,
        address _admin1,
        address _admin2)
    public
    {
        // Check that the parameters make sense
        require(block.number <= _fundingStartBlock); // The start of the fundraising should happen in the future
        require(_fundingStartBlock <= _exchangeRateChangesBlock); // The exchange rate change should happen after the start of the fundraising
        require(_exchangeRateChangesBlock <= _fundingEndBlock); // And the end of the fundraising should happen after the exchange rate change
        require (_admin1 != 0x0); // admin1 address must be set
        require (_admin2 != 0x0); // admin2 address must be set
        require (_admin1 != _admin2); // Ensure that admin accounts are different

        // Contract state
        state = ContractState.Fundraising;
        savedState = ContractState.Fundraising;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        exchangeRateChangesBlock = _exchangeRateChangesBlock;
        totalSupply = 0;

        admin1 = _admin1;
        admin2 = _admin2;
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transfer(address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(2)
    returns (bool success)
    {
        return super.transfer(_to, _value);
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transferFrom(address _from, address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(3)
    returns (bool success)
    {
        return super.transferFrom(_from, _to, _value);
    }

    /// @dev Accepts ether and creates new PLT tokens
    function createTokens()
    payable
    external
    isFundraising
    {
        require(block.number >= fundingStartBlock);
        require(block.number <= fundingEndBlock);
        require(msg.value > 0);

        // First we check the ETH cap, as it's easier to calculate, return
        // the contribution if the cap has been reached already
        uint256 checkedReceivedEth = SafeMath.add(totalReceivedEth, msg.value);
        require(checkedReceivedEth <= ETH_RECEIVED_CAP);

        // If all is fine with the ETH cap, we continue to check the
        // minimum amount of tokens and the cap for how many tokens
        // have been generated so far
        uint256 tokens = SafeMath.mul(msg.value, getCurrentTokenPrice());
        require(tokens >= TOKEN_MIN);
        uint256 checkedSupply = SafeMath.add(totalSupply, tokens);
        require(checkedSupply <= TOKEN_CREATION_CAP);

        // Only when all the checks have passed, then we update the state (ethBalances,
        // totalReceivedEth, totalSupply, and balances) of the contract
        ethBalances[msg.sender] = SafeMath.add(ethBalances[msg.sender], msg.value);
        totalReceivedEth = checkedReceivedEth;
        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;  // safeAdd not needed; bad semantics to use here

        // Log the creation of this tokens
        LogCreatePLT(msg.sender, tokens);
    }

    /// @dev Returns the current token price
    function getCurrentTokenPrice()
    private
    constant
    returns (uint256 currentPrice)
    {
        if (block.number < exchangeRateChangesBlock) {
            return TOKEN_FIRST_EXCHANGE_RATE;
        } else {
            return TOKEN_SECOND_EXCHANGE_RATE;
        }
    }

    /// @dev Redeems PLTs and records the LEO address of the sender
    function redeemTokens(string leoAddress)
    external
    isRedeeming
    {
        uint256 pltVal = balances[msg.sender];
        require(pltVal >= TOKEN_MIN); // At least TOKEN_MIN tokens have to be redeemed

        // Burn Tokens on redemption
        require(super.transfer(0x0, pltVal));
        // Log the redeeming of this tokens
        LogRedeemPLT(msg.sender, pltVal, leoAddress);
    }

    /// @dev Allows to transfer ether from the contract as soon as the minimum is reached
    function retrieveEth(uint256 _value, address _safe)
    external
    minimumReached
    onlyOwner
    {
        require(_value <= this.balance);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // send the eth to where admins agree upon
        _safe.transfer(_value);
    }

    /// @dev Ends the fundraising period and sends the ETH to wherever the admins agree upon
    function finalize(address _safe)
    external
    isFundraising
    minimumReached
    onlyOwner  // Only the admins calling this method exactly the same way can finalize the sale.
    {
        // Only allow to finalize the contract before the ending block if we already reached any of the two caps
        require(block.number > fundingEndBlock || totalSupply >= TOKEN_CREATION_CAP || totalReceivedEth >= ETH_RECEIVED_CAP);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // Move the contract to Finalized state
        state = ContractState.Finalized;
        savedState = ContractState.Finalized;

        // Send the ETH to where admins agree upon.
        _safe.transfer(this.balance);
    }

    /// @dev Starts the redeeming period
    function startRedeeming()
    external
    isFinalized // The redeeming period can only be started after the contract is finalized
    onlyOwner   // Only both admins calling this method can initiate the redeeming period
    {
        // Move the contract to Redeeming state
        state = ContractState.Redeeming;
        savedState = ContractState.Redeeming;
    }

    /// @dev Pauses the contract
    function pause()
    external
    notPaused   // Prevent the contract getting stuck in the Paused state
    onlyOwner   // Only both admins calling this method can pause the contract
    {
        // Move the contract to Paused state
        savedState = state;
        state = ContractState.Paused;
    }

    /// @dev Proceeds with the contract
    function proceed()
    external
    isPaused
    onlyOwner   // Only both admins calling this method can proceed with the contract
    {
        // Move the contract to the previous state
        state = savedState;
    }

    /// @dev Allows contributors to recover their ether in case the minimum funding goal is not reached
    function refund()
    external
    isFundraisingIgnorePaused // Refunding is only possible in the fundraising phase (no matter if paused) by definition
    {
        require(block.number > fundingEndBlock); // Prevents refund until fundraising period is over
        require(totalReceivedEth < ETH_RECEIVED_MIN);  // No refunds if the minimum has been reached

        uint256 pltVal = balances[msg.sender];
        require(pltVal > 0);
        uint256 ethVal = ethBalances[msg.sender];
        require(ethVal > 0);

        // Update the state only after all the checks have passed
        balances[msg.sender] = 0;
        ethBalances[msg.sender] = 0;
        totalSupply = SafeMath.sub(totalSupply, pltVal); // Extra safe

        // Log this refund
        LogRefund(msg.sender, ethVal);

        // Send the contributions only after we have updated all the balances
        // If you're using a contract, make sure it works with .transfer() gas limits
        msg.sender.transfer(ethVal);
    }
}

pragma solidity ^0.4.17;

import "./StandardToken.sol";

/**
 * @title The Pre-Leo Token contract.
 *
 * Credit: Taking ideas from BAT token and NET token
 */
contract PLToken is StandardToken {

    // Token metadata
    string public constant name = "Pre-Leo Token";
    string public constant symbol = "PLT";
    uint256 public constant decimals = 18;
    string public version = "0.9";

    // Fundraising parameters
    enum ContractState { Fundraising, Finalized, Redeeming, Paused }
    ContractState public state;           // Current state of the contract
    ContractState private savedState;     // State of the contract before pause

    uint256 public fundingStartBlock;        // These two blocks need to be chosen to comply with the
    uint256 public fundingEndBlock;          // start date and 28 day duration requirements
    uint256 public exchangeRateChangesBlock; // block number that triggers the exchange rate change

    address public admin1; // First administrator for multi-sig mechanism
    address public admin2; // Second administrator for multi-sig mechanism

    uint256 public constant TOKEN_FIRST_EXCHANGE_RATE = 200; // 200 PLTs per 1 ETH
    uint256 public constant TOKEN_SECOND_EXCHANGE_RATE = 175; // 175 PLTs per 1 ETH
    uint256 public constant TOKEN_CREATION_CAP = 10 * (10**6) * 10**decimals; // 10 million PLTs
    uint256 public constant ETH_RECEIVED_CAP = 50 * (10**3) * 10**decimals; // 50 000 ETH
    uint256 public constant ETH_RECEIVED_MIN = 10 * (10**3) * 10**decimals; // 10 000 ETH
    uint256 public constant TOKEN_MIN = 1 * 10**decimals; // 1 NET

    // We need to keep track of how much ether have been contributed, since we have a cap for ETH too
    uint256 public totalReceivedEth = 0;

    // Since we have different exchange rates at different stages, we need to keep track
    // of how much ether each contributed in case that we need to issue a refund
    mapping (address => uint256) private ethBalances;
    mapping (address => bytes32) private multiSigHashes; // store the hashes of admins' msg.data

    // Events used for logging
    event LogRefund(address indexed _to, uint256 _value);
    event LogCreatePLT(address indexed _to, uint256 _value);
    event LogRedeemPLT(address indexed _from, uint256 _value, string _leoAddress);

    modifier isFinalized() {
        require(state == ContractState.Finalized);
        _;
    }

    modifier isFundraising() {
        require(state == ContractState.Fundraising);
        _;
    }

    modifier isRedeeming() {
        require(state == ContractState.Redeeming);
        _;
    }

    modifier isPaused() {
        require(state == ContractState.Paused);
        _;
    }

    modifier notPaused() {
        require(state != ContractState.Paused);
        _;
    }

    modifier isFundraisingIgnorePaused() {
        require(state == ContractState.Fundraising || (state == ContractState.Paused && savedState == ContractState.Fundraising));
        _;
    }

    modifier onlyOwner() {
        // check if transaction sender is admin.
        require (msg.sender == admin1 || msg.sender == admin2);
        // if yes, store his msg.data.
        multiSigHashes[msg.sender] = keccak256(msg.data);
        // check if his stored msg.data hash equals to the one of the other admin
        if ((multiSigHashes[admin1]) == (multiSigHashes[admin2])) {
            // if yes, both admins agreed - continue.
            _;
        } else {
            // if not (yet), return.
            return;
        }
    }

    modifier minimumReached() {
        require(totalReceivedEth >= ETH_RECEIVED_MIN);
        _;
    }

    /**
     * @dev Create a new PLToken contract.
     *
     * @param _fundingStartBlock The starting block of the fundraiser (has to be in the future).
     * @param _fundingEndBlock The end block of the fundraiser (has to be after _fundingStartBlock).
     * @param _exchangeRateChangesBlock The block that changes the exchange rate (has to be between _fundingStartBlock and _fundingEndBlock).
     * @param _admin1 The first admin account that owns this contract.
     * @param _admin2 The second admin account that owns this contract.
     */
    function PLToken(
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock,
        uint256 _exchangeRateChangesBlock,
        address _admin1,
        address _admin2)
    public
    {
        // Check that the parameters make sense
        require(block.number <= _fundingStartBlock); // The start of the fundraising should happen in the future
        require(_fundingStartBlock <= _exchangeRateChangesBlock); // The exchange rate change should happen after the start of the fundraising
        require(_exchangeRateChangesBlock <= _fundingEndBlock); // And the end of the fundraising should happen after the exchange rate change
        require (_admin1 != 0x0); // admin1 address must be set
        require (_admin2 != 0x0); // admin2 address must be set
        require (_admin1 != _admin2); // Ensure that admin accounts are different

        // Contract state
        state = ContractState.Fundraising;
        savedState = ContractState.Fundraising;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        exchangeRateChangesBlock = _exchangeRateChangesBlock;
        totalSupply = 0;

        admin1 = _admin1;
        admin2 = _admin2;
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transfer(address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(2)
    returns (bool success)
    {
        return super.transfer(_to, _value);
    }

    // Overridden method to check for end of fundraising before allowing transfer of tokens
    function transferFrom(address _from, address _to, uint256 _value)
    public
    isFinalized // Only allow token transfer after the fundraising has ended
    onlyPayloadSize(3)
    returns (bool success)
    {
        return super.transferFrom(_from, _to, _value);
    }

    /// @dev Accepts ether and creates new NET tokens
    function createTokens()
    payable
    external
    isFundraising
    {
        require(block.number >= fundingStartBlock);
        require(block.number <= fundingEndBlock);
        require(msg.value > 0);

        // First we check the ETH cap, as it's easier to calculate, return
        // the contribution if the cap has been reached already
        uint256 checkedReceivedEth = SafeMath.add(totalReceivedEth, msg.value);
        require(checkedReceivedEth <= ETH_RECEIVED_CAP);

        // If all is fine with the ETH cap, we continue to check the
        // minimum amount of tokens and the cap for how many tokens
        // have been generated so far
        uint256 tokens = SafeMath.mul(msg.value, getCurrentTokenPrice());
        require(tokens >= TOKEN_MIN);
        uint256 checkedSupply = SafeMath.add(totalSupply, tokens);
        require(checkedSupply <= TOKEN_CREATION_CAP);

        // Only when all the checks have passed, then we update the state (ethBalances,
        // totalReceivedEth, totalSupply, and balances) of the contract
        ethBalances[msg.sender] = SafeMath.add(ethBalances[msg.sender], msg.value);
        totalReceivedEth = checkedReceivedEth;
        totalSupply = checkedSupply;
        balances[msg.sender] += tokens;  // safeAdd not needed; bad semantics to use here

        // Log the creation of this tokens
        LogCreatePLT(msg.sender, tokens);
    }

    /// @dev Returns the current token price
    function getCurrentTokenPrice()
    private
    constant
    returns (uint256 currentPrice)
    {
        if (block.number < exchangeRateChangesBlock) {
            return TOKEN_FIRST_EXCHANGE_RATE;
        } else {
            return TOKEN_SECOND_EXCHANGE_RATE;
        }
    }

    /// @dev Redeems PLTs and records the LEO address of the sender
    function redeemTokens(string leoAddress)
    external
    isRedeeming
    {
        uint256 netVal = balances[msg.sender];
        require(netVal >= TOKEN_MIN); // At least TOKEN_MIN tokens have to be redeemed

        // Burn Tokens on redemption
        require(super.transfer(0x0, netVal));
        // Log the redeeming of this tokens
        LogRedeemPLT(msg.sender, netVal, leoAddress);
    }

    /// @dev Allows to transfer ether from the contract as soon as the minimum is reached
    function retrieveEth(uint256 _value, address _safe)
    external
    minimumReached
    onlyOwner
    {
        require(_value <= this.balance);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // send the eth to where admins agree upon
        _safe.transfer(_value);
    }

    /// @dev Ends the fundraising period and sends the ETH to wherever the admins agree upon
    function finalize(address _safe)
    external
    isFundraising
    minimumReached
    onlyOwner  // Only the admins calling this method exactly the same way can finalize the sale.
    {
        // Only allow to finalize the contract before the ending block if we already reached any of the two caps
        require(block.number > fundingEndBlock || totalSupply >= TOKEN_CREATION_CAP || totalReceivedEth >= ETH_RECEIVED_CAP);
        // make sure a recipient was defined !
        require (_safe != 0x0);

        // Move the contract to Finalized state
        state = ContractState.Finalized;
        savedState = ContractState.Finalized;

        // Send the ETH to where admins agree upon.
        _safe.transfer(this.balance);
    }

    /// @dev Starts the redeeming period
    function startRedeeming()
    external
    isFinalized // The redeeming period can only be started after the contract is finalized
    onlyOwner   // Only both admins calling this method can initiate the redeeming period
    {
        // Move the contract to Redeeming state
        state = ContractState.Redeeming;
        savedState = ContractState.Redeeming;
    }

    /// @dev Pauses the contract
    function pause()
    external
    notPaused   // Prevent the contract getting stuck in the Paused state
    onlyOwner   // Only both admins calling this method can pause the contract
    {
        // Move the contract to Paused state
        savedState = state;
        state = ContractState.Paused;
    }

    /// @dev Proceeds with the contract
    function proceed()
    external
    isPaused
    onlyOwner   // Only both admins calling this method can proceed with the contract
    {
        // Move the contract to the previous state
        state = savedState;
    }

    /// @dev Allows contributors to recover their ether in case the minimum funding goal is not reached
    function refund()
    external
    isFundraisingIgnorePaused // Refunding is only possible in the fundraising phase (no matter if paused) by definition
    {
        require(block.number > fundingEndBlock); // Prevents refund until fundraising period is over
        require(totalReceivedEth < ETH_RECEIVED_MIN);  // No refunds if the minimum has been reached

        uint256 netVal = balances[msg.sender];
        require(netVal > 0);
        uint256 ethVal = ethBalances[msg.sender];
        require(ethVal > 0);

        // Update the state only after all the checks have passed
        balances[msg.sender] = 0;
        ethBalances[msg.sender] = 0;
        totalSupply = SafeMath.sub(totalSupply, netVal); // Extra safe

        // Log this refund
        LogRefund(msg.sender, ethVal);

        // Send the contributions only after we have updated all the balances
        // If you're using a contract, make sure it works with .transfer() gas limits
        msg.sender.transfer(ethVal);
    }
}


Add NatSpec to directDemocracy.sol

Add NatSpec to directDemocracy.sol

/// @title Direct Democracy Smart Contract Governance
/// @author ryepdx
contract DirectDemocracy is PermissionsProvider, PersistentProtectedContract {
    uint public quorum;
    uint8 public quorumPercent;
    uint public marginForVictory;
    uint8 public marginForVictoryPercent;
    uint public minimumVotingWindow;
    uint public maximumVotingWindow;

    uint VOTING_WINDOW_MIN = 600; // 10 minutes
    bytes32 OWNERS_DB = "OwnersDb";

    mapping (address => Proposal) public proposals;
    mapping (address => bool) permittedAction;

    enum Vote {
        Null, Yes, No, Abstain
    }

    struct Proposal {
        uint timestamp;
        mapping (address => Vote) votes;
        uint numVotes;
        address proposedAction;
    }

    /// @notice Create a DirectDemocracy voting smart contract.
    /// Before it will begin working properly, the address of a
    /// smart contract implementing the ApiProvider interface
    /// must be passed to setApiAddress, and the "`OWNERS_DB`"
    /// contract entry on the ApiProvider must set to the address
    /// of a smart contract implementing the OwnersDb interface.
    /// @dev Implements the PermissionsProvider interface.
    function DirectDemocracy() {
        quorum = 1;
        quorumPercent = 60;
        marginForVictory = 0;
        marginForVictoryPercent = 0;
    }

    /// @notice Check if the contract referred to should be
    /// permitted to modify contracts relying on this contract
    /// for protection.
    /// @param action
    /// @return True if the contract was voted on and passed,
    /// or if the DirectDemocracy contract isn't set up yet.
    function permitted(address action) returns (bool result) {
        return permittedAction[action]
        || api == 0x0
        || ApiProvider(api).contracts(OWNERS_DB) == 0x0;
    }

    /// @notice Add a new voting owner to the contract.
    /// May only be successfully called from an Action
    /// contract that was voted on and passed.
    /// @param owner
    /// @return True if owner was added, false otherwise.
    function addOwner(address owner) returns (bool added) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        if (dbAddress == 0x0 || !permittedSender()) return false;

        added = OwnersDb(dbAddress).addOwner(owner);

        if (added) {
            _updateMargins();
        }
    }

    /// @notice Remove a voting owner from the contract.
    /// May only be successfully called from an Action
    /// contract that was voted on and passed.
    /// @param owner
    /// @return True if owner was removed, false otherwise.
    function removeOwner(address owner) returns (bool removed) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.owners(owner);

        if (dbAddress == 0x0 || iter == 0x0 || !permittedSender()) {
            return false;
        }

        if (!db.removeOwner(owner)) return false;

        Proposal proposal;
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i+=1) {
            proposal = proposals[iter];
            iter = db.owners(iter);

            if (proposal.proposedAction == 0x0) continue;

            if (proposal.votes[owner] != Vote.Null) {
                delete proposal.votes[owner];
                proposal.numVotes -= 1;
            }
        }

        delete proposals[owner];
        _updateMargins();

        return true;
    }

    /// @notice Propose an Action contract for execution.
    /// If the Action contract is passed, it will have full
    /// permission to modify any contracts protected by this
    /// contract, including this contract itself. Each owner
    /// can only have one Action contract proposed at any
    /// given time.
    /// @dev One way the limit on proposals can be raised is
    /// by turning the proposals mapping into a two-dimensional
    /// mapping of owners to block timestamps to proposals.
    /// In fact, this is how it was done in an earlier version:
    /// https://github.com/ryepdx/etherlab/blob/386b3c5db36ac40
    /// 25408025b6f601110d36cdae4/root.sol
    /// After switching from single-action, hardcoded proposals
    /// to Action contracts, though, the loss of efficiency due
    /// to maintaining a two-dimensional mapping just didn't
    /// seem worth it anymore.
    /// @param proposedAction
    function proposeAction(address proposedAction) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        if (db.owners(msg.sender) == 0x0
            || Action(proposedAction).owner() != address(this)) {
            return;
        }

        var proposal = proposals[msg.sender];
        proposal.timestamp = block.timestamp;
        proposal.proposedAction = proposedAction;
        proposal.votes[msg.sender] = Vote.Yes;
        proposal.numVotes = 1;
    }

    /// @notice Withdraw from voting the Action contract you
    /// had previously proposed.
    function withdrawProposedAction() {
        _removeProposal(msg.sender);
    }

    /// @notice Set the minimum voter turnout necessary for
    /// an Action contract to pass. May only be successfully
    /// called from an Action contract that was passed.
    /// @param percent Voter turnout percentage as an
    /// unsigned integer. Cannot be greater than 100.
    function setQuorumPercent(uint8 percent) {
        if (percent > 100 || !permittedSender()) return;
        quorumPercent = percent;
        _updateMargins();
    }

    /// @notice Set the percentage margin by which votes
    /// in either direction must beat votes in the
    /// other direction in order for an Action contract
    /// to pass. May only be successfully called from an
    /// Action contract that was voted on and passed.
    /// @param percent Required margin percentage as an
    /// unsigned integer. Cannot be greater than 100.
    function setMarginForVictoryPercent(uint8 percent) {
        if (percent > 100 || !permittedSender()) return;
        marginForVictoryPercent = percent;
        _updateMargins();
    }

    /// @notice Set the minimum number of seconds voting
    /// must remain open before a final count is made.
    /// May only be successfully called from an Action
    /// contract that was voted on and passed.
    /// @dev Time is judged by block timestamps and thus
    /// cannot be considered precise.
    /// @param minimumWindow
    function setMinimumVotingWindow(uint minimumWindow) {
        if (!permittedSender()) return;
        minimumVotingWindow = minimumWindow;
    }

    /// @notice Set the maximum number of seconds voting
    /// may remain open before a final count is made.
    /// Cannot be set to anything between 0 and
    /// `VOTING_WINDOW_MIN`, exclusive. If set to 0,
    /// voting will remain open until quorum is reached
    /// and the margin required for victory has been
    /// achieved by either side.
    /// May only be successfully called from an Action
    /// contract that was voted on and passed.
    /// @dev Time is judged by block timestamps and thus
    /// cannot be considered precise.
    /// @param maximumWindow
    function setMaximumVotingWindow(uint maximumWindow) {
        if ((maximumWindow < VOTING_WINDOW_MIN && maximumWindow != 0)
            || !permittedSender()) {
            return;
        }
        maximumVotingWindow = maximumWindow;
    }

    /// @notice Remove all proposed Action contracts. May
    /// only be successfully called from an Action contract
    /// that was voted on and passed.
    /// @dev Calls "remove" on each Action contract as they
    /// are removed.
    function wipeProposedActions() {
        if (!permittedSender()) return;

        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.ownersTail();
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i += 1) {
            if (proposals[iter].proposedAction != 0x0) {
                Action(proposals[iter].proposedAction).remove();
                delete proposals[iter];
            }
            iter = db.owners(iter);
        }
    }

    /// @notice Vote on `action`, proposed by `owner`.
    /// @dev We require the action parameter to make sure the
    /// voter knows exactly what they are voting on. Otherwise
    /// it might be possible to pull a "bait & switch" using
    /// the "withdrawProposal" function, which could be
    /// effective if there are only two or three owners.
    /// @param owner The owner who proposed the Action.
    /// @param action The Action contract being voted on.
    /// @param vote A Vote value.
    function vote(address owner, address action, Vote vote) {
        var proposal = proposals[owner];

        if (action == 0x0
            || proposal.proposedAction != action
            || vote == Vote.Null) {
            return;
        }

        if (maximumVotingWindow == 0
            || block.timestamp <= (proposal.timestamp + maximumVotingWindow)) {

            if (proposal.votes[msg.sender] == Vote.Null) {
                proposal.numVotes += 1;
            }

            proposal.votes[msg.sender] = vote;
        }

        if (block.timestamp > (proposal.timestamp + minimumVotingWindow)) {
            var outcome = _checkVotes(owner);

            if (outcome == Vote.Null) return;

            if (outcome == Vote.Yes) {
                permittedAction[proposal.proposedAction] = true;
                Action(proposal.proposedAction).execute();
                delete permittedAction[proposal.proposedAction];
            }
            _removeProposal(owner);
        }
    }

    /// @notice Send `amount` wei to `recipient`.
    /// May only be successfully called from an Action
    /// contract that was voted on and passed.
    /// @param recipient
    /// @param amount
    function spend(address recipient, uint amount) {
        if (!permittedSender()) return;
        recipient.send(amount);
    }

    /// @notice Delete this contract and all its proposed
    /// Action contracts from the blockchain.
    function remove() {
        if (!permittedSender()) return;
        wipeProposedActions();
        super.remove();
    }

    function _removeProposal(address owner) private {
        if (proposals[owner].proposedAction == 0x0) return;
        Action(proposals[owner].proposedAction).remove();
        delete proposals[owner];
    }

    function _updateMargins() private {
        var numOwners = OwnersDb(ApiProvider(api).contracts(OWNERS_DB)).numOwners();
        quorum = (numOwners * 100) / quorumPercent;
        marginForVictory = (numOwners * 100) / marginForVictoryPercent;
    }

    function _checkVotes(address owner) private returns (Vote result) {
        var proposal = proposals[owner];
        if (proposal.numVotes < quorum) {
            return Vote.Null;
        }

        uint yesTally = 0;
        uint noTally = 0;
        var db = OwnersDb(ApiProvider(api).contracts(OWNERS_DB));
        var numOwners = db.numOwners();
        var iter = db.ownersTail();

        for (uint i=0; i < numOwners; i+=1) {
            iter = db.owners(iter);

            if (proposal.votes[iter] == Vote.Abstain || proposal.votes[iter] == Vote.Null) {
                continue;
            }

            if (proposal.votes[iter] == Vote.Yes) {
                yesTally += 1;
            } else {
                noTally -= 1;
            }
        }

        if (noTally > yesTally && (noTally - yesTally) >= marginForVictory) {
            return Vote.No;

        } else if (yesTally > noTally && (yesTally - noTally) >= marginForVictory) {
            return Vote.Yes;
        }

        return Vote.Null;
    }
}

contract DirectDemocracy is PermissionsProvider, PersistentProtectedContract {
    // PoC-8
    // include "action.sol"

    uint public quorum;
    uint8 public quorumPercent;
    uint public marginForVictory;
    uint8 public marginForVictoryPercent;
    uint public minimumVotingWindow;
    uint public maximumVotingWindow;

    uint VOTING_WINDOW_MIN = 600; // 10 minutes
    bytes32 OWNERS_DB = "OwnersDb";

    mapping (address => Proposal) public proposals;
    mapping (address => bool) permittedAction;

    enum Vote {
        Null, Yes, No, Abstain
    }

    struct Proposal {
        uint timestamp;
        mapping (address => Vote) votes;
        uint numVotes;
        address proposedAction;
    }

    function DirectDemocracy() {
        quorum = 1;
        quorumPercent = 60;
        marginForVictory = 0;
        marginForVictoryPercent = 0;
    }

    function permitted(address action) returns (bool result) {
        return permittedAction[action]
        || api == 0x0
        || ApiProvider(api).contracts(OWNERS_DB) == 0x0;
    }

    function addOwner(address owner) returns (bool added) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        if (dbAddress == 0x0 || !permittedSender()) return false;

        added = OwnersDb(dbAddress).addOwner(owner);

        if (added) {
            _updateMargins();
        }
    }

    function removeOwner(address owner) returns (bool removed) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.owners(owner);

        if (dbAddress == 0x0 || iter == 0x0 || !permittedSender()) {
            return false;
        }

        if (!db.removeOwner(owner)) return false;

        Proposal proposal;
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i+=1) {
            proposal = proposals[iter];
            iter = db.owners(iter);

            if (proposal.proposedAction == 0x0) continue;

            if (proposal.votes[owner] != Vote.Null) {
                delete proposal.votes[owner];
                proposal.numVotes -= 1;
            }
        }

        delete proposals[owner];
        _updateMargins();

        return true;
    }

    function proposeAction(address proposedAction) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        if (db.owners(msg.sender) == 0x0
            || Action(proposedAction).owner() != address(this)) {
            return;
        }

        var proposal = proposals[msg.sender];
        proposal.timestamp = block.timestamp;
        proposal.proposedAction = proposedAction;
        proposal.votes[msg.sender] = Vote.Yes;
        proposal.numVotes = 1;
    }

    function withdrawProposedAction() {
        _removeProposal(msg.sender);
    }

    function setQuorumPercent(uint8 percent) {
        if (percent > 100 || !permittedSender()) return;
        quorumPercent = percent;
        _updateMargins();
    }

    function setMarginForVictoryPercent(uint8 percent) {
        if (percent > 100 || !permittedSender()) return;
        marginForVictoryPercent = percent;
        _updateMargins();
    }

    function setMinimumVotingWindow(uint minimumWindow) {
        if (!permittedSender()) return;
        minimumVotingWindow = minimumWindow;
    }

    function setMaximumVotingWindow(uint maximumWindow) {
        if ((maximumWindow < VOTING_WINDOW_MIN && maximumWindow != 0)
            || !permittedSender()) {
            return;
        }
        maximumVotingWindow = maximumWindow;
    }

    function wipeProposedActions() {
        if (!permittedSender()) return;

        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.ownersTail();
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i += 1) {
            if (proposals[iter].proposedAction != 0x0) {
                Action(proposals[iter].proposedAction).remove();
                delete proposals[iter];
            }
            iter = db.owners(iter);
        }
    }

    function vote(address owner, address action, Vote vote) {
        // We require the action parameter to make sure the voter knows
        // exactly what they are voting on, to prevent "bait & switch."
        var proposal = proposals[owner];

        if (action == 0x0
            || proposal.proposedAction != action
            || vote == Vote.Null) {
            return;
        }

        if (maximumVotingWindow == 0
            || block.timestamp <= (proposal.timestamp + maximumVotingWindow)) {

            if (proposal.votes[msg.sender] == Vote.Null) {
                proposal.numVotes += 1;
            }

            proposal.votes[msg.sender] = vote;
        }

        if (block.timestamp > (proposal.timestamp + minimumVotingWindow)) {
            var outcome = _checkVotes(owner);

            if (outcome == Vote.Null) return;

            if (outcome == Vote.Yes) {
                permittedAction[proposal.proposedAction] = true;
                Action(proposal.proposedAction).execute();
                delete permittedAction[proposal.proposedAction];
            }
            _removeProposal(owner);
        }
    }

    function spend(address recipient, uint amount) {
        if (!permittedSender()) return;
        recipient.send(amount);
    }

    function remove() {
        if (!permittedSender()) return;
        wipeProposedActions();
        super.remove();
    }

    function _removeProposal(address owner) private {
        if (proposals[owner].proposedAction == 0x0) return;
        Action(proposals[owner].proposedAction).remove();
        delete proposals[owner];
    }

    function _updateMargins() private {
        var numOwners = OwnersDb(ApiProvider(api).contracts(OWNERS_DB)).numOwners();
        quorum = (numOwners * 100) / quorumPercent;
        marginForVictory = (numOwners * 100) / marginForVictoryPercent;
    }

    function _checkVotes(address owner) private returns (Vote result) {
        var proposal = proposals[owner];
        if (proposal.numVotes < quorum) {
            return Vote.Null;
        }

        uint yesTally = 0;
        uint noTally = 0;
        var db = OwnersDb(ApiProvider(api).contracts(OWNERS_DB));
        var numOwners = db.numOwners();
        var iter = db.ownersTail();

        for (uint i=0; i < numOwners; i+=1) {
            iter = db.owners(iter);

            if (proposal.votes[iter] == Vote.Abstain || proposal.votes[iter] == Vote.Null) {
                continue;
            }

            if (proposal.votes[iter] == Vote.Yes) {
                yesTally += 1;
            } else {
                noTally -= 1;
            }
        }

        if (noTally > yesTally && (noTally - yesTally) >= marginForVictory) {
            return Vote.No;

        } else if (yesTally > noTally && (yesTally - noTally) >= marginForVictory) {
            return Vote.Yes;
        }

        return Vote.Null;
    }
}


fix bad var name

fix bad var name

/*
    Copyright 2017-2018 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity ^0.4.24;

import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

contract PositionToken is StandardToken, Ownable {

    string public name;
    string public symbol;
    uint8 public decimals;

    uint8 public MARKET_SIDE; // 0 = Long, 1 = Short

    constructor(
        string tokenName,
        string tokenSymbol,
        uint8 tokenDecimals,
        uint8 marketSide
    ) public
    {
        name = tokenName;
        symbol = tokenSymbol;
        decimals = tokenDecimals;
        MARKET_SIDE = marketSide;
    }

    /// @dev Called by our collateral pool to create a long or short position token. These tokens are minted,
    /// and then transferred to our recipient who is the party who is minting these tokens.  The collateral pool
    /// is the only caller (acts as the owner) because collateral must be deposited / locked prior to minting of new
    /// position tokens
    /// @param qtyToMint quantity of position tokens to mint (in base units)
    /// @param recipient the person minting and receiving these position tokens.
    function mintAndSendToken(uint256 qtyToMint, address recipient) external onlyOwner {
        totalSupply_ = totalSupply_.add(qtyToMint);                 // add to total supply
        balances[recipient] = balances[recipient].add(qtyToMint);   // transfer to recipient balance
        emit Transfer(address(0), recipient, qtyToMint);            // fire event to show balance.
    }

    /// @dev Called by our collateral pool when redemption occurs.  This means that either a single user is redeeming
    /// both short and long tokens in order to claim their collateral, or the contract has settled, and only a single
    /// side of the tokens are needed to redeem (handled by the collateral pool)
    /// @param qtyToRedeem quantity of tokens to burn (remove from supply / circulation)
    /// @param redeemer the person redeeming these tokens (who are we taking the balance from)
    function redeemToken(uint256 qtyToRedeem, address redeemer) external onlyOwner {
        // reduce the redeemer's balances.  This will throw if not enough balance to reduce!
        balances[redeemer] = balances[redeemer].sub(qtyToRedeem);
        totalSupply_ = totalSupply_.sub(qtyToRedeem);                    // reduce total supply
        emit Transfer(redeemer, address(0), qtyToRedeem);           // fire event to update balances
    }
}

/*
    Copyright 2017-2018 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity ^0.4.24;

import "openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

contract PositionToken is StandardToken, Ownable {

    string public name;
    string public symbol;
    uint8 public decimals;

    uint8 public MARKET_SIDE; // 0 = Long, 1 = Short

    constructor(
        string tokenName,
        string tokenSymbol,
        uint8 tokenDecimals,
        uint8 marketSide
    ) public
    {
        name = tokenName;
        symbol = tokenSymbol;
        decimals = tokenDecimals;
        MARKET_SIDE = marketSide;
    }

    /// @dev Called by our collateral pool to create a long or short position token. These tokens are minted,
    /// and then transferred to our recipient who is the party who is minting these tokens.  The collateral pool
    /// is the only caller (acts as the owner) because collateral must be deposited / locked prior to minting of new
    /// position tokens
    /// @param qtyToMint quantity of position tokens to mint (in base units)
    /// @param recipient the person minting and receiving these position tokens.
    function mintAndSendToken(uint256 qtyToMint, address recipient) external onlyOwner {
        totalSupply_ = totalSupply_.add(qtyToMint);                 // add to total supply
        balances[recipient] = balances[recipient].add(qtyToMint);   // transfer to recipient balance
        emit Transfer(address(0), recipient, qtyToMint);            // fire event to show balance.
    }

    /// @dev Called by our collateral pool when redemption occurs.  This means that either a single user is redeeming
    /// both short and long tokens in order to claim their collateral, or the contract has settled, and only a single
    /// side of the tokens are needed to redeem (handled by the collateral pool)
    /// @param qtyToRedeem quantity of tokens to burn (remove from supply / circulation)
    /// @param redeemer the person redeeming these tokens (who are we taking the balance from)
    function redeemToken(uint256 qtyToRedeem, address redeemer) external onlyOwner {
        // reduce the redeemer's balances.  This will throw if not enough balance to reduce!
        balances[redeemer] = balances[redeemer].sub(qtyToRedeem);
        totalSupply_ = totalSupply_.sub(_value);                    // reduce total supply
        emit Transfer(redeemer, address(0), qtyToRedeem);           // fire event to update balances
    }
}