From 59d7ccff88d23551d08fed6af88d06a720942bf4 Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Thu, 13 Nov 2025 10:50:01 +0100 Subject: [PATCH 1/5] feat: tge unlock starts at launch date --- contracts/vesting.tmy/src/vesting.tmy.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index a58f878..ac16dae 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -99,11 +99,14 @@ namespace vestingtoken // Calculate the vesting end time time_point vesting_end = vesting_start + category.vesting_period; + // Calculate the claimable amount: + // + tokens allocated * TGE unlock percentage + int64_t claimable = vesting_allocation.tokens_allocated.amount * category.tge_unlock; + // Check if vesting period after cliff has started if (now >= cliff_finished) { // Calculate the total claimable amount - int64_t claimable = 0; if (now >= vesting_end) { claimable = vesting_allocation.tokens_allocated.amount; @@ -113,9 +116,8 @@ namespace vestingtoken // Calculate the percentage of the vesting period that has passed double vesting_finished = static_cast((now - vesting_start).count()) / category.vesting_period.count(); // Calculate the claimable amount: - // + tokens allocated * TGE unlock percentage // + tokens allocated * % of vesting time that has passed * what is left after TGE unlock - claimable = vesting_allocation.tokens_allocated.amount * ((1.0 - category.tge_unlock) * vesting_finished + category.tge_unlock); + claimable += vesting_allocation.tokens_allocated.amount * (1.0 - category.tge_unlock) * vesting_finished; // Ensure the claimable amount is not greater than the total allocated amount claimable = std::min(claimable, vesting_allocation.tokens_allocated.amount); } From 3eac1cac02c90ac1e9505045eb158345e43a324d Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Thu, 13 Nov 2025 11:27:47 +0100 Subject: [PATCH 2/5] fix: tge unlock should happen at launch date --- contracts/vesting.tmy/src/vesting.tmy.cpp | 45 +++++++++++------------ 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index ac16dae..6320ae5 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -99,37 +99,36 @@ namespace vestingtoken // Calculate the vesting end time time_point vesting_end = vesting_start + category.vesting_period; - // Calculate the claimable amount: - // + tokens allocated * TGE unlock percentage - int64_t claimable = vesting_allocation.tokens_allocated.amount * category.tge_unlock; + // Calculate the claimable amount so far + int64_t total_allocated = vesting_allocation.tokens_allocated.amount; + // Portion unlocked at launch date (TGE unlock) + int64_t claimable = static_cast(total_allocated * category.tge_unlock); - // Check if vesting period after cliff has started - if (now >= cliff_finished) + if (now >= vesting_end) { - // Calculate the total claimable amount - if (now >= vesting_end) - { - claimable = vesting_allocation.tokens_allocated.amount; - } - else - { - // Calculate the percentage of the vesting period that has passed - double vesting_finished = static_cast((now - vesting_start).count()) / category.vesting_period.count(); - // Calculate the claimable amount: - // + tokens allocated * % of vesting time that has passed * what is left after TGE unlock - claimable += vesting_allocation.tokens_allocated.amount * (1.0 - category.tge_unlock) * vesting_finished; - // Ensure the claimable amount is not greater than the total allocated amount - claimable = std::min(claimable, vesting_allocation.tokens_allocated.amount); - } + // All tokens have vested by end of schedule + claimable = total_allocated; + } + else if (now >= cliff_finished) + { + // After cliff, linear vesting for the remaining tokens + double vesting_finished = static_cast((now - vesting_start).count()) / category.vesting_period.count(); + int64_t remaining_after_tge = total_allocated - claimable; + claimable = std::min(total_allocated, + claimable + static_cast(remaining_after_tge * vesting_finished)); + } + // Only process if there's anything new to claim + if (claimable > vesting_allocation.tokens_claimed.amount) + { total_claimable += claimable - vesting_allocation.tokens_claimed.amount; // Update the tokens_claimed field eosio::asset tokens_claimed = eosio::asset(claimable, vesting_allocation.tokens_claimed.symbol); - if (claimable == vesting_allocation.tokens_allocated.amount) + if (claimable == total_allocated) { - // Erase and update iterator correctly + // Fully vested and claimed: remove the row iter = vesting_table.erase(iter); } else @@ -143,7 +142,7 @@ namespace vestingtoken } else { - ++iter; + ++iter; } } From ac72a8e8ae49706f0ee3162dc76ab02dad34215e Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Fri, 5 Dec 2025 11:17:16 +0100 Subject: [PATCH 3/5] fix: double special round categories --- contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp index 833c7ac..18d46e5 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -61,6 +61,9 @@ namespace vestingtoken {26, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Platform Dev {27, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Staking & Infra Rewards {28, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Ecosystem + {29, {days(0 * 30), days(42), days(6 * 30), 0.15}}, // Double Special Round - Full + {30, {days(0 * 30), days(42), days(3 * 30), 0.3}}, // Double Special Round - Part 1 + {31, {days(0 * 30), days(42 + 3 * 30), days(3 * 30), 0.0}}, // Double Special Round - Part 2 // Testing categories: #ifdef BUILD_TEST {997, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // TESTING ONLY From 5faa585b0269c244ffe4aeaaa4c62ba1c8aa9a3c Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Fri, 5 Dec 2025 11:24:34 +0100 Subject: [PATCH 4/5] fix: updated delay time for new vesting categories --- contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp index 18d46e5..12b1b13 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -61,9 +61,9 @@ namespace vestingtoken {26, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Platform Dev {27, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Staking & Infra Rewards {28, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Ecosystem - {29, {days(0 * 30), days(42), days(6 * 30), 0.15}}, // Double Special Round - Full - {30, {days(0 * 30), days(42), days(3 * 30), 0.3}}, // Double Special Round - Part 1 - {31, {days(0 * 30), days(42 + 3 * 30), days(3 * 30), 0.0}}, // Double Special Round - Part 2 + {29, {days(0 * 30), days(26), days(6 * 30), 0.15}}, // Double Special Round - Full + {30, {days(0 * 30), days(26), days(3 * 30), 0.3}}, // Double Special Round - Part 1 + {31, {days(0 * 30), days(26 + 3 * 30), days(3 * 30), 0.0}}, // Double Special Round - Part 2 // Testing categories: #ifdef BUILD_TEST {997, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // TESTING ONLY From 5af8d60fa46d52f5710f5ac75af976bed4cde670 Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Wed, 10 Dec 2025 19:58:13 +0100 Subject: [PATCH 5/5] fix: fixed the tokens_claim check --- contracts/vesting.tmy/src/vesting.tmy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index 6320ae5..79ef6c6 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -176,7 +176,7 @@ namespace vestingtoken // Checks to verify new allocation is valid eosio::check(iter->tokens_allocated.amount == old_amount.amount, "Old amount does not match existing allocation"); eosio::check(iter->vesting_category_type == old_category_id, "Old category does not match existing allocation"); - eosio::check(iter->tokens_claimed.amount < new_amount.amount, "New amount is less than the amount already claimed"); + eosio::check(iter->tokens_claimed.amount <= new_amount.amount, "New amount is less than the amount already claimed"); // Modify the table row data, and update the table vesting_table.modify(iter, get_self(), [&](auto &row)