contract VSUpayments {

    using SafeMath for uint256;

    Token public militaryToken;
    address public owner;
    uint public lockUpEnd;
    uint public awardsEnd;
    mapping (address => uint256) public award;
    mapping (address => uint256) public withdrawn;
    uint256 public totalAwards = 0;
    uint256 public currentAwards = 0;

    /**
        @param _militaryToken The address of the MilitaryToken contract.
    */
    constructor(address _militaryToken) public {
        militaryToken = Token(_militaryToken);
        owner = msg.sender;
        lockUpEnd = now + (365 days);
        awardsEnd = now + (730 days);
    }

    /**
        @dev Restricts privileged functions to the contract owner.
    */
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    /**
        @dev Functions that can only be called before the end of the lock-up period.
    */
    modifier preEnd() {
        require(now < lockUpEnd);
        _;
    }

    /**
        @dev Functions that can only be called after the end of the lock-up period.
    */
    modifier postEnd() {
        require(lockUpEnd <= now);
        _;
    }

    /**
        @dev Functions that can only be called if the awards are fully funded.
     */
    modifier funded() {
        require(currentAwards <= militaryToken.balanceOf(address(this)));
        _;
    }

    modifier awardsAllowed() {
        require(now < awardsEnd);
        _;
    }

    /**
        @notice Changes contract ownership.
        @param  newOwner The address of the new owner.
    */
    function transferOwnership(address newOwner) public onlyOwner {
        if(newOwner != address(0)) {
            owner = newOwner;
        }
    }

    /**
        @notice Award MILs to people that will become available after lock-up period (if funded).
        @param _to The address that the MILs are being awarded to.  After lock-up period awardee will be able to acquire awarded tokens.
        @param _MILs The number of MILS being awarded.
    */
    function awardMILsTo(address _to, uint256 _MILs) public onlyOwner awardsAllowed {
        
        award[_to] = award[_to].add(_MILs);
        totalAwards = totalAwards.add(_MILs);
        currentAwards = currentAwards.add(_MILs);
    }

    /**
        @notice Transfers awarded MILs to the caller's account.
    */
    function withdrawMILs(uint256 _MILs) public postEnd funded {
        uint256 daysSinceEnd = (now - lockUpEnd) / 1 days;
        uint256 maxPct = min(((daysSinceEnd / 30 + 1) * 25), 100);
        uint256 allowed = award[msg.sender];
        allowed = allowed * maxPct / 100;
        allowed -= withdrawn[msg.sender];
        require(_MILs <= allowed);
        militaryToken.transfer(msg.sender, _MILs);
        withdrawn[msg.sender] += _MILs;
        currentAwards -= _MILs;
    }

    /**
        @notice Transfers any un-awarded MILs to the contract owner.
    */
    function recoverUnawardedMILs() public  {
        uint256 MILs = militaryToken.balanceOf(address(this));
        if(totalAwards < MILs) {
            militaryToken.transfer(owner, MILs - totalAwards);
        }
    }

    function min(uint a, uint b) private pure returns (uint) {
        return a < b ? a : b;
    }
}
/**
 @title VSUpayments
 @author Stanford K. Easley
 
 */
function withdrawMILs(uint256 _MILs) public postEnd funded {
    uint256 daysSinceEnd = (now - lockUpEnd) / 1 days;
    uint256 maxPct = min(((daysSinceEnd / 30 + 1) * 25), 100);
    uint256 allowed = award[msg.sender];
    allowed = allowed * maxPct / 100;
    allowed -= withdrawn[msg.sender];
    require(_MILs <= allowed);
    militaryToken.transfer(msg.sender, _MILs);
    withdrawn[msg.sender] += _MILs;
    currentAwards -= _MILs;
}

/**
 @notice Transfers awarded MILs to the caller's account.
 */