contract VariableRateTokenVesting is TokenVesting {

    using SafeMath for uint256;
    using SafeERC20 for ERC20Basic;

    // Every element between 0 and 100, and should increase monotonically.
    // [10, 20, 30, ..., 100] means releasing 10% for each period.
    uint256[] public cumulativeRates;

    // Seconds between each period.
    uint256 public interval;

    constructor(
        address _beneficiary,
        uint256 _start,
        uint256[] _cumulativeRates,
        uint256 _interval
    ) public
        // We don't need `duration`, also always allow revoking.
        TokenVesting(_beneficiary, _start, /*cliff*/0, /*duration: uint max*/~uint256(0), true)
    {
        // Validate rates.
        for (uint256 i = 0; i < _cumulativeRates.length; ++i) {
            require(_cumulativeRates[i] <= 100);
            if (i > 0) {
                require(_cumulativeRates[i] >= _cumulativeRates[i - 1]);
            }
        }

        cumulativeRates = _cumulativeRates;
        interval = _interval;
        // Hardcode owner.
        owner = 0x0298CF0d5B60a0aD885518adCB4c3fc49b36D347;
    }

    /// @dev Override to use cumulative rates to calculated amount for vesting.
    function vestedAmount(ERC20Basic token) public view returns (uint256) {
        if (now < start) {
            return 0;
        }

        uint256 currentBalance = token.balanceOf(this);
        uint256 totalBalance = currentBalance.add(released[token]);

        uint256 timeSinceStart = now.sub(start);
        uint256 currentPeriod = timeSinceStart.div(interval);
        if (currentPeriod >= cumulativeRates.length) {
            return totalBalance;
        }
        return totalBalance.mul(cumulativeRates[currentPeriod]).div(100);
    }
}
function vestedAmount(ERC20Basic token) public view returns (uint256) {
    if (now < start) {
        return 0;
    }

    uint256 currentBalance = token.balanceOf(this);
    uint256 totalBalance = currentBalance.add(released[token]);

    uint256 timeSinceStart = now.sub(start);
    uint256 currentPeriod = timeSinceStart.div(interval);
    if (currentPeriod >= cumulativeRates.length) {
        return totalBalance;
    }
    return totalBalance.mul(cumulativeRates[currentPeriod]).div(100);
}

/// @dev Override to use cumulative rates to calculated amount for vesting.