From 97dd74826918b978acd96301eda8c909898f3b23 Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Fri, 13 Sep 2024 17:27:18 +0200 Subject: [PATCH 1/6] feat: unlock at TGE and migrate function --- .../include/vesting.tmy/vesting.tmy.hpp | 40 ++++++++--- contracts/vesting.tmy/src/vesting.tmy.cpp | 71 ++++++++++++++++--- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp index 22c3a26..aacb265 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -25,18 +25,26 @@ namespace vestingtoken microseconds cliff_period; microseconds start_delay; microseconds vesting_period; + float tge_unlock; }; static const std::map vesting_categories = { - {1, {days(6 * 30), days(0 * 30), days(2 * 365)}}, // Seed Private Sale, - {2, {days(6 * 30), days(6 * 30), days(2 * 365)}}, // Strategic Partnerships Private Sale, - {3, {days(0 * 30), days(0 * 30), days(0 * 30)}}, // Public Sale (DO NOT USED YET), - {4, {days(0 * 30), days(1 * 365), days(5 * 365)}}, // Team and Advisors, Ecosystem - {5, {days(0 * 30), days(0 * 30), days(1 * 365)}}, // Legal and Compliance - {6, {days(0 * 30), days(0 * 30), days(2 * 365)}}, // Reserves, Partnerships, Liquidly Allocation - {7, {days(0 * 30), days(0 * 30), days(5 * 365)}}, // Community and Marketing, Platform Dev, Infra Rewards - - {999, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20)}}, // TESTING ONLY + // Depreciated: + {1, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // Seed Private Sale (DEPRECIATED), + {2, {days(6 * 30), days(6 * 30), days(2 * 365), 0.0}}, // Strategic Partnerships Private Sale (DEPRECIATED), + // Old: + {3, {days(0 * 30), days(0 * 30), days(0 * 30), 0.0}}, // Public Sale (DO NOT USED YET), + {4, {days(0 * 30), days(1 * 365), days(5 * 365), 0.0}}, // Team and Advisors, Ecosystem + {5, {days(0 * 30), days(0 * 30), days(1 * 365), 0.0}}, // Legal and Compliance + {6, {days(0 * 30), days(0 * 30), days(2 * 365), 0.0}}, // Reserves, Partnerships, Liquidly Allocation + {7, {days(0 * 30), days(0 * 30), days(5 * 365), 0.0}}, // Community and Marketing, Platform Dev, Infra Rewards + // New (replacing depreciated): + {8, {days(0 * 30), days(0 * 30), days(2 * 365), 0.05}}, // Seed (Early Bird) + {9, {days(0 * 30), days(0 * 30), days(2 * 365), 0.025}}, // Seed (Last Chance) + {10, {days(0 * 30), days(0 * 30), days(2 * 365), 1.0}}, // Public (TGE) + + {998, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.5}}, // TESTING ONLY + {999, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.0}}, // TESTING ONLY }; class [[eosio::contract("vesting.tmy")]] vestingToken : public eosio::contract @@ -105,8 +113,22 @@ namespace vestingtoken */ [[eosio::action]] void withdraw(eosio::name holder); + /** + * @details Migrates an allocation to a new amount and category + * + * @internal Auth required by the contract + * + * @param sender {name} - The account name of the sender who created the allocation. + * @param holder {name} - The account name of the token holder. + * @param allocation_id {uint64_t} - The ID of the allocation to be migrated. + * @param amount {asset} - The new amount of tokens to be assigned. + * @param category_id {int} - The new vesting category for the assigned tokens. + */ + [[eosio::action]] void migratealloc(eosio::name sender, name holder, uint64_t allocation_id, eosio::asset amount, int category_id); + using setsettings_action = action_wrapper<"setsettings"_n, &vestingToken::setsettings>; using assigntokens_action = action_wrapper<"assigntokens"_n, &vestingToken::assigntokens>; using withdraw_action = action_wrapper<"withdraw"_n, &vestingToken::withdraw>; + using migratealloc_action = action_wrapper<"migratealloc"_n, &vestingToken::migratealloc>; }; } diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index 8faddbd..db2b59b 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -2,6 +2,14 @@ namespace vestingtoken { + void check_asset(const eosio::asset &asset) + { + auto sym = asset.symbol; + eosio::check(sym.is_valid(), "invalid amount symbol"); + eosio::check(sym == vestingToken::system_resource_currency, "Symbol does not match system resource currency"); + eosio::check(sym.precision() == vestingToken::system_resource_currency.precision(), "Symbol precision does not match"); + eosio::check(asset.amount > 0, "Amount must be greater than 0"); + } void vestingToken::setsettings(string sales_date_str, string launch_date_str) { @@ -21,11 +29,7 @@ namespace vestingtoken eosio::check(vesting_categories.contains(category_id), "Invalid vesting category"); // Check the symbol is correct and valid - auto sym = amount.symbol; - eosio::check(sym.is_valid(), "invalid amount symbol"); - eosio::check(sym == system_resource_currency, "Symbol does not match system resource currency"); - eosio::check(sym.precision() == system_resource_currency.precision(), "Symbol precision does not match"); - eosio::check(amount.amount > 0, "Amount must be greater than 0"); + check_asset(amount); // Create a new vesting schedule vesting_allocations vesting_table(get_self(), holder.value); @@ -93,14 +97,14 @@ namespace vestingtoken vesting_category category = vesting_categories.at(vesting_allocation.vesting_category_type); - time_point vesting_start = launch_date + vesting_allocation.time_since_sale_start + category.start_delay; - time_point cliff_end = vesting_start + category.cliff_period; + time_point vesting_start = launch_date + category.start_delay; + time_point cliff_over = vesting_start + category.cliff_period; // Calculate the vesting end time time_point vesting_end = vesting_start + category.vesting_period; // Check if vesting period after cliff has started - if (now >= cliff_end) + if (now >= cliff_over) { // Calculate the total claimable amount int64_t claimable = 0; @@ -111,7 +115,7 @@ namespace vestingtoken else { double vesting_finished = static_cast((now - vesting_start).count()) / category.vesting_period.count(); - claimable = vesting_allocation.tokens_allocated.amount * vesting_finished; + claimable = vesting_allocation.tokens_allocated.amount * (vesting_finished + category.tge_unlock); } total_claimable += claimable - vesting_allocation.tokens_claimed.amount; @@ -123,7 +127,6 @@ namespace vestingtoken } } - eosio::print("]"); if (total_claimable > 0) { // Transfer the tokens to the holder @@ -135,4 +138,52 @@ namespace vestingtoken .send(); } } + + // Migrates an allocation to a new amount and category + void vestingToken::migratealloc(eosio::name sender, name holder, uint64_t allocation_id, eosio::asset amount, int category_id) + { + require_auth(get_self()); + + // Check if the provided category exists in the map + eosio::check(vesting_categories.contains(category_id), "Invalid vesting category"); + + // Check the symbol is correct and valid + check_asset(amount); + + // Get the vesting allocations + vesting_allocations vesting_table(get_self(), holder.value); + auto iter = vesting_table.find(allocation_id); + eosio::check(iter != vesting_table.end(), "Allocation not found"); + + // Calculate the change in the allocation amount + int64_t amount_change = amount.amount - iter->tokens_allocated.amount; + + // Modify the table row data, and update the table + vesting_table.modify(iter, get_self(), [&](auto &row) + { + row.tokens_allocated = amount; + row.vesting_category_type = category_id; }); + + // Notify the holder + eosio::require_recipient(holder); + + // If new tokens were allocated, then send them to the contract + if (amount_change > 0) + { + eosio::action({sender, "active"_n}, + token_contract_name, + "transfer"_n, + std::make_tuple(sender, get_self(), amount_change, std::string("Allocated vested funds"))) + .send(); + } + // If tokens were removed, send them back to the sender + else if (amount_change < 0) + { + eosio::action({get_self(), "active"_n}, + token_contract_name, + "transfer"_n, + std::make_tuple(get_self(), sender, -amount_change, std::string("Refunded vested funds"))) + .send(); + } + } } \ No newline at end of file From d75d10505bccbefcdd83ed6446d1c541d641006a Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Mon, 16 Sep 2024 10:07:33 +0200 Subject: [PATCH 2/6] feat: Depreciated categories --- contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp | 2 ++ contracts/vesting.tmy/src/vesting.tmy.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp index aacb265..5279858 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -47,6 +47,8 @@ namespace vestingtoken {999, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.0}}, // TESTING ONLY }; + static const std::map depreciated_categories = {{1, true}, {2, true}}; + class [[eosio::contract("vesting.tmy")]] vestingToken : public eosio::contract { public: diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index db2b59b..af314df 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -27,6 +27,8 @@ namespace vestingtoken { // Check if the provided category exists in the map eosio::check(vesting_categories.contains(category_id), "Invalid vesting category"); + // Check if the category is not in the list of depreciated categories + eosio::check(depreciated_categories.at(category_id), "Category is depreciated"); // Check the symbol is correct and valid check_asset(amount); From 4a10e4bc843b2b459899184085ffe995f0c13745 Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Mon, 16 Sep 2024 10:11:16 +0200 Subject: [PATCH 3/6] feat: check on old category and amount --- .../include/vesting.tmy/vesting.tmy.hpp | 2 +- contracts/vesting.tmy/src/vesting.tmy.cpp | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp index 5279858..0fceff8 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -126,7 +126,7 @@ namespace vestingtoken * @param amount {asset} - The new amount of tokens to be assigned. * @param category_id {int} - The new vesting category for the assigned tokens. */ - [[eosio::action]] void migratealloc(eosio::name sender, name holder, uint64_t allocation_id, eosio::asset amount, int category_id); + [[eosio::action]] void migratealloc(eosio::name sender, name holder, uint64_t allocation_id, eosio::asset old_amount, eosio::asset new_amount, int old_category_id, int new_category_id); using setsettings_action = action_wrapper<"setsettings"_n, &vestingToken::setsettings>; using assigntokens_action = action_wrapper<"assigntokens"_n, &vestingToken::assigntokens>; diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index af314df..0635238 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -142,29 +142,36 @@ namespace vestingtoken } // Migrates an allocation to a new amount and category - void vestingToken::migratealloc(eosio::name sender, name holder, uint64_t allocation_id, eosio::asset amount, int category_id) + void vestingToken::migratealloc(eosio::name sender, name holder, uint64_t allocation_id, eosio::asset old_amount, eosio::asset new_amount, int old_category_id, int new_category_id) { require_auth(get_self()); // Check if the provided category exists in the map - eosio::check(vesting_categories.contains(category_id), "Invalid vesting category"); + eosio::check(vesting_categories.contains(new_category_id), "Invalid vesting category"); // Check the symbol is correct and valid - check_asset(amount); + check_asset(new_amount); // Get the vesting allocations vesting_allocations vesting_table(get_self(), holder.value); auto iter = vesting_table.find(allocation_id); eosio::check(iter != vesting_table.end(), "Allocation not found"); + // Check the new category is not in the list of depreciated categories + eosio::check(depreciated_categories.at(new_category_id), "Category is depreciated"); + + // Check the old amount and category match the existing allocation + eosio::check(iter->tokens_allocated == old_amount, "Old amount does not match existing allocation"); + eosio::check(iter->vesting_category_type == old_category_id, "Old category does not match existing allocation"); + // Calculate the change in the allocation amount - int64_t amount_change = amount.amount - iter->tokens_allocated.amount; + int64_t amount_change = new_amount.amount - iter->tokens_allocated.amount; // Modify the table row data, and update the table vesting_table.modify(iter, get_self(), [&](auto &row) { - row.tokens_allocated = amount; - row.vesting_category_type = category_id; }); + row.tokens_allocated = new_amount; + row.vesting_category_type = new_category_id; }); // Notify the holder eosio::require_recipient(holder); From c9377d178e5a0bcd68daf403e106a1e7906ea1a2 Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Mon, 16 Sep 2024 15:35:20 +0200 Subject: [PATCH 4/6] feat: tge unlock logic and testing categories --- .../vesting.tmy/include/vesting.tmy/vesting.tmy.hpp | 9 ++++++--- contracts/vesting.tmy/src/vesting.tmy.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp index 0fceff8..1219f41 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -25,14 +25,14 @@ namespace vestingtoken microseconds cliff_period; microseconds start_delay; microseconds vesting_period; - float tge_unlock; + double tge_unlock; }; static const std::map vesting_categories = { // Depreciated: {1, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // Seed Private Sale (DEPRECIATED), {2, {days(6 * 30), days(6 * 30), days(2 * 365), 0.0}}, // Strategic Partnerships Private Sale (DEPRECIATED), - // Old: + // Unchanged: {3, {days(0 * 30), days(0 * 30), days(0 * 30), 0.0}}, // Public Sale (DO NOT USED YET), {4, {days(0 * 30), days(1 * 365), days(5 * 365), 0.0}}, // Team and Advisors, Ecosystem {5, {days(0 * 30), days(0 * 30), days(1 * 365), 0.0}}, // Legal and Compliance @@ -41,8 +41,11 @@ namespace vestingtoken // New (replacing depreciated): {8, {days(0 * 30), days(0 * 30), days(2 * 365), 0.05}}, // Seed (Early Bird) {9, {days(0 * 30), days(0 * 30), days(2 * 365), 0.025}}, // Seed (Last Chance) - {10, {days(0 * 30), days(0 * 30), days(2 * 365), 1.0}}, // Public (TGE) + {10, {days(0 * 30), days(14), days(0 * 365), 1.0}}, // Public (TGE) + // Public sale has a delay of 14 days to accommodate the "right of withdrawal" under EU's MICA regulations + // TESTING ONLY: + {997, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // TESTING ONLY {998, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.5}}, // TESTING ONLY {999, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.0}}, // TESTING ONLY }; diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index 0635238..ace0580 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -28,7 +28,7 @@ namespace vestingtoken // Check if the provided category exists in the map eosio::check(vesting_categories.contains(category_id), "Invalid vesting category"); // Check if the category is not in the list of depreciated categories - eosio::check(depreciated_categories.at(category_id), "Category is depreciated"); + eosio::check(!depreciated_categories.contains(category_id), "Category is depreciated"); // Check the symbol is correct and valid check_asset(amount); @@ -100,13 +100,13 @@ namespace vestingtoken vesting_category category = vesting_categories.at(vesting_allocation.vesting_category_type); time_point vesting_start = launch_date + category.start_delay; - time_point cliff_over = vesting_start + category.cliff_period; + time_point cliff_finished = vesting_start + category.cliff_period; // Calculate the vesting end time time_point vesting_end = vesting_start + category.vesting_period; // Check if vesting period after cliff has started - if (now >= cliff_over) + if (now >= cliff_finished) { // Calculate the total claimable amount int64_t claimable = 0; @@ -117,7 +117,7 @@ namespace vestingtoken else { double vesting_finished = static_cast((now - vesting_start).count()) / category.vesting_period.count(); - claimable = vesting_allocation.tokens_allocated.amount * (vesting_finished + category.tge_unlock); + claimable = vesting_allocation.tokens_allocated.amount * std::min((vesting_finished + category.tge_unlock), 1.0); } total_claimable += claimable - vesting_allocation.tokens_claimed.amount; From 188d35b6a4975b9313e09e173d640593f61d9b8f Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Mon, 16 Sep 2024 16:08:28 +0200 Subject: [PATCH 5/6] feat: updated the claimable amount --- contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp | 4 ++-- contracts/vesting.tmy/src/vesting.tmy.cpp | 8 +++++++- 2 files changed, 9 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 1219f41..752252d 100644 --- a/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp +++ b/contracts/vesting.tmy/include/vesting.tmy/vesting.tmy.hpp @@ -29,7 +29,7 @@ namespace vestingtoken }; static const std::map vesting_categories = { - // Depreciated: + // DEPRECIATED: {1, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // Seed Private Sale (DEPRECIATED), {2, {days(6 * 30), days(6 * 30), days(2 * 365), 0.0}}, // Strategic Partnerships Private Sale (DEPRECIATED), // Unchanged: @@ -46,7 +46,7 @@ namespace vestingtoken // TESTING ONLY: {997, {days(6 * 30), days(0 * 30), days(2 * 365), 0.0}}, // TESTING ONLY - {998, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.5}}, // TESTING ONLY + {998, {eosio::seconds(0), eosio::seconds(10), eosio::seconds(20), 0.5}}, // TESTING ONLY {999, {eosio::seconds(10), eosio::seconds(10), eosio::seconds(20), 0.0}}, // TESTING ONLY }; diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index ace0580..41b14b8 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -116,8 +116,14 @@ namespace vestingtoken } else { + // Calculate the percentage of the vesting period that has passed double vesting_finished = static_cast((now - vesting_start).count()) / category.vesting_period.count(); - claimable = vesting_allocation.tokens_allocated.amount * std::min((vesting_finished + category.tge_unlock), 1.0); + // 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); + // Ensure the claimable amount is not greater than the total allocated amount + claimable = std::min(claimable, vesting_allocation.tokens_allocated.amount); } total_claimable += claimable - vesting_allocation.tokens_claimed.amount; From cbc9c8e8b8b33b2387af6ed2bddec08af8ae9682 Mon Sep 17 00:00:00 2001 From: Jack Tanner Date: Mon, 16 Sep 2024 21:21:16 +0200 Subject: [PATCH 6/6] fix: fixed migrateAllocation --- contracts/vesting.tmy/src/vesting.tmy.cpp | 36 ++++++++++------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/contracts/vesting.tmy/src/vesting.tmy.cpp b/contracts/vesting.tmy/src/vesting.tmy.cpp index 41b14b8..f3fddf3 100644 --- a/contracts/vesting.tmy/src/vesting.tmy.cpp +++ b/contracts/vesting.tmy/src/vesting.tmy.cpp @@ -11,6 +11,12 @@ namespace vestingtoken eosio::check(asset.amount > 0, "Amount must be greater than 0"); } + void check_category(int category_id) + { + eosio::check(vesting_categories.contains(category_id), "Invalid new vesting category"); + eosio::check(!depreciated_categories.contains(category_id), "New category is depreciated"); + } + void vestingToken::setsettings(string sales_date_str, string launch_date_str) { require_auth(get_self()); @@ -25,12 +31,7 @@ namespace vestingtoken void vestingToken::assigntokens(eosio::name sender, eosio::name holder, eosio::asset amount, int category_id) { - // Check if the provided category exists in the map - eosio::check(vesting_categories.contains(category_id), "Invalid vesting category"); - // Check if the category is not in the list of depreciated categories - eosio::check(!depreciated_categories.contains(category_id), "Category is depreciated"); - - // Check the symbol is correct and valid + check_category(category_id); check_asset(amount); // Create a new vesting schedule @@ -152,10 +153,7 @@ namespace vestingtoken { require_auth(get_self()); - // Check if the provided category exists in the map - eosio::check(vesting_categories.contains(new_category_id), "Invalid vesting category"); - - // Check the symbol is correct and valid + check_category(new_category_id); check_asset(new_amount); // Get the vesting allocations @@ -163,15 +161,10 @@ namespace vestingtoken auto iter = vesting_table.find(allocation_id); eosio::check(iter != vesting_table.end(), "Allocation not found"); - // Check the new category is not in the list of depreciated categories - eosio::check(depreciated_categories.at(new_category_id), "Category is depreciated"); - - // Check the old amount and category match the existing allocation - eosio::check(iter->tokens_allocated == old_amount, "Old amount does not match existing allocation"); + // 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"); - - // Calculate the change in the allocation amount - int64_t amount_change = new_amount.amount - iter->tokens_allocated.amount; + 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) @@ -182,13 +175,16 @@ namespace vestingtoken // Notify the holder eosio::require_recipient(holder); + // // Calculate the change in the allocation amount + int64_t amount_change = new_amount.amount - old_amount.amount; + // If new tokens were allocated, then send them to the contract if (amount_change > 0) { eosio::action({sender, "active"_n}, token_contract_name, "transfer"_n, - std::make_tuple(sender, get_self(), amount_change, std::string("Allocated vested funds"))) + std::make_tuple(sender, get_self(), eosio::asset(amount_change, old_amount.symbol), std::string("Re-allocated vested funds"))) .send(); } // If tokens were removed, send them back to the sender @@ -197,7 +193,7 @@ namespace vestingtoken eosio::action({get_self(), "active"_n}, token_contract_name, "transfer"_n, - std::make_tuple(get_self(), sender, -amount_change, std::string("Refunded vested funds"))) + std::make_tuple(get_self(), sender, eosio::asset(-amount_change, old_amount.symbol), std::string("Refunded vested funds"))) .send(); } }