This implementation adds support for vesting "cliffs" on top-ups to the Vesting Vault system. When funds are added to an existing vault (top-up), a new cliff can be defined specifically for those new tokens using a SubSchedule system.
- Stores basic vault information including address, owner, token, and total amount
- Supports initial vesting schedule with optional cliff
- Located in:
backend/src/models/vault.js
- Handles multiple vesting schedules per vault
- Each top-up creates a new sub-schedule with its own cliff configuration
- Tracks amount released per sub-schedule
- Located in:
backend/src/models/subSchedule.js
- SQL migration script for creating vaults and sub_schedules tables
- Includes proper indexes and foreign key constraints
- Located in:
backend/migrations/001_create_vaults_and_sub_schedules.sql
createVault()- Creates new vault with initial vesting parameterstopUpVault()- Adds funds to existing vault with optional cliffcalculateReleasableAmount()- Calculates releasable tokens across all sub-schedulesreleaseTokens()- Releases tokens respecting individual cliff periodsgetVaultWithSubSchedules()- Retrieves vault with all sub-schedules
- Updated to use VestingService for vault operations
- Added methods:
topUpVault(),getVaultDetails(),calculateReleasableAmount(),releaseTokens()
processTopUpEvent()- Handles blockchain top-up eventsprocessReleaseEvent()- Processes token release eventscalculateSubScheduleReleasable()- Vesting calculation helper
POST /api/vault/top-up- Top-up vault with cliff configurationGET /api/vault/:vaultAddress/details- Get vault with sub-schedulesGET /api/vault/:vaultAddress/releasable- Calculate releasable amountPOST /api/vault/release- Release tokens from vault
POST /api/indexing/top-up- Process top-up blockchain eventsPOST /api/indexing/release- Process release blockchain events
const vault = await vestingService.createVault(
'0xadmin...',
'0xvault...',
'0xowner...',
'0xtoken...',
'1000.0',
new Date('2024-01-01'),
new Date('2025-01-01'),
null // no initial cliff
);const topUp = await vestingService.topUpVault(
'0xadmin...',
'0xvault...',
'500.0',
'0xtransaction...',
86400, // 1 day cliff in seconds
2592000 // 30 days vesting in seconds
);const releasable = await vestingService.calculateReleasableAmount(
'0xvault...',
new Date() // as of date
);POST /api/vault/top-up
{
"adminAddress": "0xadmin...",
"vaultAddress": "0xvault...",
"topUpConfig": {
"topUpAmount": "500.0",
"transactionHash": "0xabc...",
"cliffDuration": 86400,
"vestingDuration": 2592000
}
}GET /api/vault/0xvault.../detailsGET /api/vault/0xvault.../releasable?asOfDate=2024-02-01T00:00:00ZComprehensive test suite located at backend/test/vesting-topup.test.js covering:
- Sub-schedule creation with and without cliffs
- Releasable amount calculations
- Indexing service integration
- Error handling
- Full flow integration tests
- Multiple Sub-Schedules: Each top-up creates its own vesting schedule
- Independent Cliffs: Each sub-schedule can have its own cliff period
- Pro-rata Releases: Token releases are distributed proportionally across sub-schedules
- Audit Trail: All operations are logged for compliance
- Blockchain Integration: Indexing service handles on-chain events
✅ SubSchedule List: Implemented SubSchedule model within Vault system ✅ Complex Logic: Handles multiple vesting schedules with independent cliffs ✅ Stretch Goal: Successfully implemented as complex feature with full functionality
id(UUID, Primary Key)vault_address(VARCHAR, Unique)owner_address(VARCHAR)token_address(VARCHAR)total_amount(DECIMAL)start_date,end_date,cliff_date(TIMESTAMP)is_active(BOOLEAN)
id(UUID, Primary Key)vault_id(UUID, Foreign Key)top_up_amount(DECIMAL)top_up_transaction_hash(VARCHAR, Unique)top_up_timestamp(TIMESTAMP)cliff_duration,vesting_duration(INTEGER)cliff_date,vesting_start_date(TIMESTAMP)amount_released(DECIMAL)is_active(BOOLEAN)
The implementation provides a robust, scalable solution for managing vesting cliffs on top-ups while maintaining backward compatibility with existing vault functionality.