This implementation adds Diversified Vesting functionality to the existing vesting contract system. Instead of vesting a single token, beneficiaries can now receive a basket of multiple assets (e.g., 50% Project Token, 25% XLM, 25% USDC) that vest simultaneously according to the same schedule.
- Problem: Single-token vesting exposes beneficiaries to high volatility
- Solution: Diversified baskets reduce exposure to any single asset's price movements
- Example: If project token drops 80%, beneficiary still has stable value from XLM/USDC portions
- Problem: Senior developers require stable financial planning
- Solution: Mix of project tokens (upside potential) + stable assets (predictable value)
- Result: More competitive offers for top talent
- Junior Developer: 30% ProjectToken, 35% XLM, 35% USDC (stability-focused)
- Senior Developer: 50% ProjectToken, 25% XLM, 25% USDC (balanced)
- Executive: 70% ProjectToken, 15% XLM, 15% USDC (upside-focused)
- Advisor: 40% ProjectToken, 30% XLM, 30% USDC (conservative)
#[contracttype]
#[derive(Clone)]
pub struct AssetAllocation {
pub asset_id: Address, // Token contract address
pub total_amount: i128, // Total tokens allocated
pub released_amount: i128, // Tokens already claimed
pub locked_amount: i128, // Tokens locked for collateral
pub percentage: u32, // Percentage in basis points (10000 = 100%)
}#[contracttype]
#[derive(Clone)]
pub struct Vault {
pub allocations: Vec<AssetAllocation>, // Basket of assets (NEW)
pub keeper_fee: i128,
pub staked_amount: i128,
pub owner: Address,
pub delegate: Option<Address>,
pub title: String,
pub start_time: u64,
pub end_time: u64,
pub creation_time: u64,
pub step_duration: u64,
pub is_initialized: bool,
pub is_irrevocable: bool,
pub is_transferable: bool,
pub is_frozen: bool,
}pub fn create_vault_diversified_full(
env: Env,
owner: Address,
asset_basket: Vec<AssetAllocation>,
start_time: u64,
end_time: u64,
keeper_fee: i128,
is_revocable: bool,
is_transferable: bool,
step_duration: u64,
title: String,
) -> u64Features:
- Validates asset basket percentages sum to 10000 (100%)
- Transfers all assets from admin to contract
- Creates vault with multiple asset allocations
pub fn claim_tokens_diversified(env: Env, vault_id: u64) -> Vec<(Address, i128)>Process:
- Calculate vested amount for each asset based on time elapsed
- Determine claimable amount (vested - already released)
- Transfer each asset to beneficiary
- Update vault state with new released amounts
- Return list of (asset_id, claimed_amount) pairs
fn validate_asset_basket(basket: &Vec<AssetAllocation>) -> boolValidation Rules:
- Percentages must sum to exactly 10000 (100%)
- Basket cannot be empty
- Each asset amount must be positive
- Each percentage must be between 1 and 10000
The system supports multiple vesting schedules, all applied uniformly across the asset basket:
vested_amount = (allocation.total_amount * elapsed_time) / total_durationcompleted_steps = elapsed_time / step_duration
vested_amount = (allocation.total_amount * completed_steps) / total_stepsunlocked_percentage = sum(milestone.percentage for milestone in unlocked_milestones)
vested_amount = (allocation.total_amount * unlocked_percentage) / 100- Oracle-based conditions must be met before any vesting begins
- Once cliff is passed, normal vesting schedule applies to all assets
// Create asset basket: 50% ProjectToken, 25% XLM, 25% USDC
let mut asset_basket = vec![&env];
asset_basket.push_back(AssetAllocation {
asset_id: project_token_address,
total_amount: 10_000_0000000, // 10,000 tokens
released_amount: 0,
locked_amount: 0,
percentage: 5000, // 50%
});
asset_basket.push_back(AssetAllocation {
asset_id: xlm_address,
total_amount: 2_500_0000000, // 2,500 XLM
released_amount: 0,
locked_amount: 0,
percentage: 2500, // 25%
});
asset_basket.push_back(AssetAllocation {
asset_id: usdc_address,
total_amount: 2_500_0000000, // 2,500 USDC
released_amount: 0,
locked_amount: 0,
percentage: 2500, // 25%
});
// Create 4-year vesting vault
let vault_id = client.create_vault_diversified_full(
&beneficiary,
&asset_basket,
&start_time,
&(start_time + 4 * 365 * 24 * 60 * 60), // 4 years
&0, // no keeper fee
&true, // revocable
&true, // transferable
&0, // linear vesting
&String::from_str(&env, "Senior Dev Package"),
);// After 1 year (25% vested), beneficiary claims:
let claimed_assets = client.claim_tokens_diversified(&vault_id);
// Result:
// - 2,500 Project Tokens (25% of 10,000)
// - 625 XLM (25% of 2,500)
// - 625 USDC (25% of 2,500)The implementation maintains full backward compatibility:
pub fn claim_tokens(env: Env, vault_id: u64, claim_amount: i128) -> i128- Works with single-asset vaults (allocations.len() == 1)
- Panics if used on multi-asset vaults with helpful error message
- Old vault creation functions create single-asset allocations internally
- Existing vaults continue to work without modification
- New diversified functions are additive, not replacing
pub fn lock_tokens_for_asset(env: Env, vault_id: u64, asset_id: Address, amount: i128)
pub fn unlock_tokens_for_asset(env: Env, vault_id: u64, asset_id: Address, amount: i128)pub fn claim_by_lender_for_asset(
env: Env,
vault_id: u64,
lender: Address,
asset_id: Address,
amount: i128,
) -> i128pub fn get_vault_statistics(env: Env, vault_id: u64) -> (i128, i128, i128, u32)
// Returns: (total_value, released_value, claimable_value, asset_count)pub fn get_vault_asset_basket(env: Env, vault_id: u64) -> Vec<AssetAllocation>
pub fn update_vault_asset_basket(env: Env, vault_id: u64, new_basket: Vec<AssetAllocation>)- Asset percentages must sum to exactly 10000 (100%)
- Prevents over-allocation or under-allocation errors
- Enforced at vault creation and basket updates
- Only whitelisted tokens can be used in asset baskets
- Prevents malicious or invalid token addresses
- Admin-controlled whitelist management
- Only vault owner can claim tokens
- Only admin can create/modify vaults
- Only authorized bridges can lock/unlock tokens
- All assets in a basket are claimed atomically
- Either all transfers succeed or all fail
- Prevents partial claim states
- Single function call claims all assets simultaneously
- Reduces transaction costs compared to individual claims
- Efficient iteration over asset allocations
- Asset allocations stored in single Vec
- Minimal storage overhead per additional asset
- Efficient serialization/deserialization
- Asset basket validation
- Vesting calculations for each asset
- Claiming logic with multiple assets
- Error conditions and edge cases
- End-to-end vault creation and claiming
- Interaction with token contracts
- Multi-asset scenarios with real tokens
- Random asset basket generation
- Invariant checking (percentages always sum to 100%)
- Fuzz testing with various time scenarios
- No immediate changes required - existing vaults continue working
- Gradual adoption - new vaults can use diversified features
- Optional migration - existing vaults can be migrated if desired
- Design asset baskets based on compensation strategy
- Use diversified creation functions for new vaults
- Implement diversified claiming in frontend applications
- Allow periodic rebalancing of asset percentages
- Maintain target allocations as token prices change
- Admin-controlled rebalancing triggers
- Support for assets that generate yield
- Automatic reinvestment or distribution options
- Integration with DeFi protocols
- Support for assets on different blockchains
- Bridge integration for cross-chain transfers
- Unified claiming across multiple chains
- Different vesting schedules per asset
- Conditional vesting based on performance metrics
- Dynamic cliff adjustments
The Diversified Vesting implementation provides a powerful solution for creating more attractive and stable compensation packages. By allowing multiple assets to vest simultaneously, it reduces risk for beneficiaries while maintaining the incentive alignment benefits of traditional token vesting.
The implementation is designed to be:
- Backward compatible with existing systems
- Flexible for various compensation strategies
- Secure with comprehensive validation
- Efficient in terms of gas usage
- Extensible for future enhancements
This makes it an ideal solution for projects looking to attract and retain top talent with competitive, risk-adjusted compensation packages.