@kamino-finance/farms-sdk
Version:
101 lines • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateVestingConfig = validateVestingConfig;
exports.calculateClaimablePercentAtTime = calculateClaimablePercentAtTime;
exports.calculateVestingAtTime = calculateVestingAtTime;
/**
* Validates VestingConfig parameters to ensure they are within acceptable bounds.
* @throws Error if any validation fails
*/
function validateVestingConfig(config) {
const { vestingStartTimestampSeconds, vestingDurationSeconds, minClaimablePercentStart: minClaimablePercent, maxClaimablePercentEnd: maxClaimablePercent, growthRate, } = config;
if (vestingStartTimestampSeconds < 0) {
throw new Error(`Invalid vestingStartTimestampSeconds: ${vestingStartTimestampSeconds}. Must be >= 0.`);
}
if (vestingDurationSeconds <= 0) {
throw new Error(`Invalid vestingDurationSeconds: ${vestingDurationSeconds}. Must be > 0.`);
}
if (minClaimablePercent <= 0 || minClaimablePercent >= 100) {
throw new Error(`Invalid minClaimablePercent: ${minClaimablePercent}. Must be between 0 and 100 (exclusive).`);
}
if (maxClaimablePercent <= 0 || maxClaimablePercent > 100) {
throw new Error(`Invalid maxClaimablePercent: ${maxClaimablePercent}. Must be between 0 (exclusive) and 100 (inclusive).`);
}
if (minClaimablePercent >= maxClaimablePercent) {
throw new Error(`Invalid percentage range: minClaimablePercent (${minClaimablePercent}) must be less than maxClaimablePercent (${maxClaimablePercent}).`);
}
if (growthRate <= 0) {
throw new Error(`Invalid growthRate: ${growthRate}. Must be > 0.`);
}
}
/**
* Calculates the claimable percentage at a specific point in time using an exponential curve.
*
* Formula: claimablePercent = MIN + (MAX - MIN) * ((e^(k*t/T) - 1) / (e^k - 1))
* where:
* - MIN = minimum claimable (10%)
* - MAX = maximum claimable (100%)
* - k = growth rate (2.506)
* - t = time elapsed
* - T = total vesting duration
*
* @param currentTimestamp - The current timestamp in seconds
* @param config - Vesting configuration
* @returns Claimable percentage (capped between minClaimablePercentStart and maxClaimablePercentEnd)
*/
function calculateClaimablePercentAtTime(currentTimestamp, config) {
validateVestingConfig(config);
const { vestingStartTimestampSeconds: vestingStartTimestamp, vestingDurationSeconds, minClaimablePercentStart: minClaimablePercent, maxClaimablePercentEnd: maxClaimablePercent, growthRate, } = config;
if (currentTimestamp < vestingStartTimestamp) {
return 0;
}
const elapsedSeconds = currentTimestamp - vestingStartTimestamp;
if (elapsedSeconds >= vestingDurationSeconds) {
return maxClaimablePercent;
}
// Calculate normalized time (0 to 1)
const normalizedTime = elapsedSeconds / vestingDurationSeconds;
// Exponential curve calculation
const exponentialFactor = (Math.exp(growthRate * normalizedTime) - 1) / (Math.exp(growthRate) - 1);
const claimablePercent = minClaimablePercent +
(maxClaimablePercent - minClaimablePercent) * exponentialFactor;
return Math.max(minClaimablePercent, Math.min(maxClaimablePercent, claimablePercent));
}
/**
* Calculates the full vesting details for a user at the current point in time.
* This function can be called by the crank at any time to determine how much
* a user can claim and how much they would forfeit.
*
* @param userAllocation - User's total allocation
* @param currentTimestamp - Current timestamp in seconds (defaults to now)
* @param config - Vesting configuration
* @returns Complete vesting calculation
*/
function calculateVestingAtTime(userAllocation, currentTimestamp = Math.floor(Date.now() / 1000), config) {
validateVestingConfig(config);
if (userAllocation.isNegative()) {
throw new Error(`Invalid userAllocation: ${userAllocation.toString()}. Must be >= 0.`);
}
const { vestingStartTimestampSeconds: vestingStartTimestamp, vestingDurationSeconds, } = config;
// Calculate elapsed time
const elapsedSeconds = Math.max(0, currentTimestamp - vestingStartTimestamp);
const daysElapsed = elapsedSeconds / (24 * 60 * 60);
// Check if fully vested
const isFullyVested = elapsedSeconds >= vestingDurationSeconds;
// Calculate claimable percentage
const claimablePercent = calculateClaimablePercentAtTime(currentTimestamp, config);
const forfeitablePercent = 100 - claimablePercent;
// Calculate actual amounts
const claimableAmount = userAllocation.mul(claimablePercent).div(100);
const forfeitableAmount = userAllocation.sub(claimableAmount);
return {
calculatedAt: currentTimestamp,
daysElapsed,
claimablePercent,
forfeitablePercent,
claimableAmount,
forfeitableAmount,
isFullyVested,
};
}
//# sourceMappingURL=vestingUtils.js.map