diff --git a/contract-shared-headers/eosdactokens_shared.hpp b/contract-shared-headers/eosdactokens_shared.hpp index 39fa3b21..9c3537fe 100644 --- a/contract-shared-headers/eosdactokens_shared.hpp +++ b/contract-shared-headers/eosdactokens_shared.hpp @@ -176,10 +176,14 @@ namespace eosdac { asset liquid = get_balance(owner, code, sym.code()); + auto canDeleteStakeTime = true; + auto existing_stake = stakes.find(owner.value); if (existing_stake != stakes.end()) { liquid -= existing_stake->stake; + canDeleteStakeTime = false; } + auto unstakes_itr = unstakes_idx.find(owner.value); while (unstakes_itr != unstakes_idx.end() && unstakes_itr->account == owner) { if (unstakes_itr->released()) { @@ -188,12 +192,20 @@ namespace eosdac { unstakes_itr = unstakes_idx.erase(unstakes_itr); } else { print("NOT yet released"); - + canDeleteStakeTime = false; // otherwise it still negatively impacts the liquid balance liquid -= unstakes_itr->stake; unstakes_itr++; } } + if (canDeleteStakeTime) { + staketimes_table staketimes(code, dac.dac_id.value); + + auto existing_time = staketimes.find(owner.value); + if (existing_time != staketimes.end()) { + staketimes.erase(existing_time); + } + } return liquid; } diff --git a/contracts/eosdactokens/eosdactokens.cpp b/contracts/eosdactokens/eosdactokens.cpp index b9baca30..1fab24d5 100644 --- a/contracts/eosdactokens/eosdactokens.cpp +++ b/contracts/eosdactokens/eosdactokens.cpp @@ -403,10 +403,10 @@ namespace eosdac { } // send notification for unstake at current delay and then stake with new delay - name custodian_contract = dac.account_for_type(dacdir::CUSTODIAN); - name vote_contract = dac.account_for_type(dacdir::VOTE_WEIGHT); - name notify_contract = (vote_contract) ? vote_contract : custodian_contract; - asset current_stake = eosdac::get_staked(account, get_self(), token_symbol); + const auto custodian_contract = dac.account_for_type_maybe(dacdir::CUSTODIAN); + const auto vote_contract = dac.account_for_type_maybe(dacdir::VOTE_WEIGHT); + const auto notify_contract = (vote_contract) ? *vote_contract : *custodian_contract; + asset current_stake = eosdac::get_staked(account, get_self(), token_symbol); account_stake_delta stake_deltas_sub = {account, -current_stake, unstake_time_before}; account_stake_delta stake_deltas_add = {account, current_stake, unstake_time}; diff --git a/contracts/eosdactokens/eosdactokens.test.ts b/contracts/eosdactokens/eosdactokens.test.ts index 0e9323b1..85fd9352 100644 --- a/contracts/eosdactokens/eosdactokens.test.ts +++ b/contracts/eosdactokens/eosdactokens.test.ts @@ -224,8 +224,8 @@ describe('EOSDacTokens', () => { let staker1: l.Account; let staker2: l.Account; before(async () => { - staker1 = await l.AccountManager.createAccount(); - staker2 = await l.AccountManager.createAccount(); + staker1 = await l.AccountManager.createAccount('abcstaker1'); + staker2 = await l.AccountManager.createAccount('abcstaker2'); await shared.dac_token_contract.issue( issuer.name, '30000.0000 ABC', @@ -548,6 +548,118 @@ describe('EOSDacTokens', () => { }); }); }); + context('resetstakes', async () => { + let user1: Account; + let user2: Account; + before(async () => { + user1 = await l.AccountManager.createAccount('abcuser1'); + user2 = await l.AccountManager.createAccount('abcuser2'); + await shared.dac_token_contract.issue( + issuer.name, + '200.0000 ABC', + 'initial issued tokens', + { from: issuer } + ); + await shared.dac_token_contract.transfer( + issuer.name, + user1.name, + '100.0000 ABC', + 'please take these tokens for staking', + validAuths + ); + await shared.dac_token_contract.transfer( + issuer.name, + user2.name, + '100.0000 ABC', + 'please take these tokens for staking', + validAuths + ); + }); + context('staketime', async () => { + it('should populate staketimesTable', async () => { + await shared.dac_token_contract.staketime(user1, 14, '4,ABC', { + from: user1, + }); + await shared.dac_token_contract.staketime(user2, 14, '4,ABC', { + from: user2, + }); + await l.assertRowsEqual( + shared.dac_token_contract.staketimeTable({ scope: 'abcdac' }), + [ + { + account: user1.name, + delay: 14, + }, + { + account: user2.name, + delay: 14, + }, + ] + ); + }); + it('staking and unstaking', async () => { + await shared.dac_token_contract.stake(user1.name, '10.0000 ABC', { + from: user1, + }); + await shared.dac_token_contract.unstake(user1.name, '4.0000 ABC', { + from: user1, + }); + // await l.sleep(10_000); + await shared.dac_token_contract.unstake(user1.name, '6.0000 ABC', { + from: user1, + }); + await l.assertRowsEqual( + shared.dac_token_contract.staketimeTable({ scope: 'abcdac' }), + [ + { + account: user1.name, + delay: 14, + }, + { + account: user2.name, + delay: 14, + }, + ] + ); + }); + it('unstake 1 should not reset staketime', async () => { + await l.sleep(4_000); + await shared.dac_token_contract.claimunstkes(user1.name, '4,ABC', { + from: user1, + }); + + await l.assertRowsEqual( + shared.dac_token_contract.staketimeTable({ scope: 'abcdac' }), + [ + { + account: user1.name, + delay: 14, + }, + { + account: user2.name, + delay: 14, + }, + ] + ); + }); + it('unstake 2nd should reset staketime', async () => { + await l.sleep(10_000); + + await shared.dac_token_contract.claimunstkes(user1.name, '4,ABC', { + from: user1, + }); + await l.assertRowsEqual( + shared.dac_token_contract.staketimeTable({ scope: 'abcdac' }), + [ + { + account: user2.name, + delay: 14, + }, + ] + ); + }); + }); + }); context('transfer', async () => { let sender: l.Account; diff --git a/daccustodian.old/daccustodian.abi b/daccustodian.old/daccustodian.abi deleted file mode 100644 index 030d5c13..00000000 --- a/daccustodian.old/daccustodian.abi +++ /dev/null @@ -1,1148 +0,0 @@ -{ - "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", - "version": "eosio::abi/1.2", - "types": [ - { - "new_type_name": "state_value_variant", - "type": "variant_uint32_uint64_int64_bool_int64[]_name_string_time_point_sec" - }, - { - "new_type_name": "state_value_variant2", - "type": "variant_int8_uint8_int32_uint32_int64_uint64_int128_uint128_bool_int64[]_name_string_time_point_sec_asset_extended_asset" - } - ], - "structs": [ - { - "name": "account_balance_delta", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "balance_delta", - "type": "asset" - } - ] - }, - { - "name": "account_stake_delta", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "stake_delta", - "type": "asset" - }, - { - "name": "unstake_delay", - "type": "uint32" - } - ] - }, - { - "name": "account_weight_delta", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "weight_delta", - "type": "int64" - }, - { - "name": "weight_delta_quorum", - "type": "int64" - } - ] - }, - { - "name": "appointcust", - "base": "", - "fields": [ - { - "name": "cust", - "type": "name[]" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "balanceobsv", - "base": "", - "fields": [ - { - "name": "account_balance_deltas", - "type": "account_balance_delta[]" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "candidate", - "base": "", - "fields": [ - { - "name": "candidate_name", - "type": "name" - }, - { - "name": "requestedpay", - "type": "asset" - }, - { - "name": "rank", - "type": "uint64" - }, - { - "name": "gap_filler", - "type": "uint64" - }, - { - "name": "total_vote_power", - "type": "uint64" - }, - { - "name": "is_active", - "type": "uint8" - }, - { - "name": "number_voters", - "type": "uint32" - }, - { - "name": "avg_vote_time_stamp", - "type": "time_point_sec" - } - ] - }, - { - "name": "candperm", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "permission", - "type": "name" - } - ] - }, - { - "name": "claimbudget", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "claimpay", - "base": "", - "fields": [ - { - "name": "payid", - "type": "uint64" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "clearrank", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "contr_config", - "base": "", - "fields": [ - { - "name": "lockupasset", - "type": "extended_asset" - }, - { - "name": "maxvotes", - "type": "uint8" - }, - { - "name": "numelected", - "type": "uint8" - }, - { - "name": "periodlength", - "type": "uint32" - }, - { - "name": "should_pay_via_service_provider", - "type": "bool" - }, - { - "name": "initial_vote_quorum_percent", - "type": "uint32" - }, - { - "name": "token_supply_theshold", - "type": "uint64" - }, - { - "name": "vote_quorum_percent", - "type": "uint32" - }, - { - "name": "auth_threshold_high", - "type": "uint8" - }, - { - "name": "auth_threshold_mid", - "type": "uint8" - }, - { - "name": "auth_threshold_low", - "type": "uint8" - }, - { - "name": "lockup_release_time_delay", - "type": "uint32" - }, - { - "name": "requested_pay_max", - "type": "extended_asset" - } - ] - }, - { - "name": "contr_state2", - "base": "", - "fields": [ - { - "name": "lastperiodtime", - "type": "time_point_sec" - }, - { - "name": "data", - "type": "pair_uint8_state_value_variant[]" - } - ] - }, - { - "name": "custodian", - "base": "", - "fields": [ - { - "name": "cust_name", - "type": "name" - }, - { - "name": "requestedpay", - "type": "asset" - }, - { - "name": "total_vote_power", - "type": "uint64" - }, - { - "name": "rank", - "type": "uint64" - }, - { - "name": "number_voters", - "type": "uint32" - }, - { - "name": "avg_vote_time_stamp", - "type": "time_point_sec" - } - ] - }, - { - "name": "custodian2", - "base": "", - "fields": [ - { - "name": "cust_name", - "type": "name" - }, - { - "name": "requestedpay", - "type": "asset" - }, - { - "name": "rank", - "type": "uint64" - }, - { - "name": "total_vote_power", - "type": "uint64" - }, - { - "name": "number_voters", - "type": "uint32" - }, - { - "name": "avg_vote_time_stamp", - "type": "time_point_sec" - } - ] - }, - { - "name": "dacglobals", - "base": "", - "fields": [ - { - "name": "data", - "type": "pair_string_state_value_variant2[]" - } - ] - }, - { - "name": "fillstate", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "firecand", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "lockupStake", - "type": "bool" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "firecust", - "base": "", - "fields": [ - { - "name": "cust", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "flagcandprof", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "reason", - "type": "string" - }, - { - "name": "reporter", - "type": "name" - }, - { - "name": "block", - "type": "bool" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "migrate1", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "migrate2", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "migraterank", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "newperiod", - "base": "", - "fields": [ - { - "name": "message", - "type": "string" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "nominate", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "nominatecane", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "requestedpay", - "type": "asset" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "pair_string_state_value_variant2", - "base": "", - "fields": [ - { - "name": "key", - "type": "string" - }, - { - "name": "value", - "type": "state_value_variant2" - } - ] - }, - { - "name": "pair_uint8_state_value_variant", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint8" - }, - { - "name": "value", - "type": "state_value_variant" - } - ] - }, - { - "name": "pay", - "base": "", - "fields": [ - { - "name": "key", - "type": "uint64" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "quantity", - "type": "extended_asset" - } - ] - }, - { - "name": "paycpu", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "proxy", - "base": "", - "fields": [ - { - "name": "proxy", - "type": "name" - }, - { - "name": "total_weight", - "type": "int64" - } - ] - }, - { - "name": "regproxy", - "base": "", - "fields": [ - { - "name": "proxy", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "rejectcuspay", - "base": "", - "fields": [ - { - "name": "payid", - "type": "uint64" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "removecand", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "removecstvte", - "base": "", - "fields": [ - { - "name": "voter", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "removecuspay", - "base": "", - "fields": [ - { - "name": "payid", - "type": "uint64" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "resigncust", - "base": "", - "fields": [ - { - "name": "cust", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "runnewperiod", - "base": "", - "fields": [ - { - "name": "message", - "type": "string" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "setbudget", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - }, - { - "name": "percentage", - "type": "uint16" - } - ] - }, - { - "name": "setperm", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "permission", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "stakeobsv", - "base": "", - "fields": [ - { - "name": "account_stake_deltas", - "type": "account_stake_delta[]" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "stprofile", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "profile", - "type": "string" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "tstaddcust", - "base": "", - "fields": [ - { - "name": "cust", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "unregproxy", - "base": "", - "fields": [ - { - "name": "proxy", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "unsetbudget", - "base": "", - "fields": [ - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "updatebio", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "bio", - "type": "string" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "updateconfige", - "base": "", - "fields": [ - { - "name": "new_config", - "type": "contr_config" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "updatereqpay", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "requestedpay", - "type": "asset" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "vote", - "base": "", - "fields": [ - { - "name": "voter", - "type": "name" - }, - { - "name": "proxy", - "type": "name" - }, - { - "name": "candidates", - "type": "name[]" - }, - { - "name": "vote_time_stamp", - "type": "time_point_sec" - }, - { - "name": "vote_count", - "type": "uint8" - } - ] - }, - { - "name": "votecust", - "base": "", - "fields": [ - { - "name": "voter", - "type": "name" - }, - { - "name": "newvotes", - "type": "name[]" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "voteproxy", - "base": "", - "fields": [ - { - "name": "voter", - "type": "name" - }, - { - "name": "proxy", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "weightobsv", - "base": "", - "fields": [ - { - "name": "account_weight_deltas", - "type": "account_weight_delta[]" - }, - { - "name": "dac_id", - "type": "name" - } - ] - }, - { - "name": "withdrawcane", - "base": "", - "fields": [ - { - "name": "cand", - "type": "name" - }, - { - "name": "dac_id", - "type": "name" - } - ] - } - ], - "actions": [ - { - "name": "appointcust", - "type": "appointcust", - "ricardian_contract": "" - }, - { - "name": "balanceobsv", - "type": "balanceobsv", - "ricardian_contract": "" - }, - { - "name": "claimbudget", - "type": "claimbudget", - "ricardian_contract": "" - }, - { - "name": "claimpay", - "type": "claimpay", - "ricardian_contract": "" - }, - { - "name": "clearrank", - "type": "clearrank", - "ricardian_contract": "" - }, - { - "name": "fillstate", - "type": "fillstate", - "ricardian_contract": "" - }, - { - "name": "firecand", - "type": "firecand", - "ricardian_contract": "" - }, - { - "name": "firecust", - "type": "firecust", - "ricardian_contract": "" - }, - { - "name": "flagcandprof", - "type": "flagcandprof", - "ricardian_contract": "" - }, - { - "name": "migrate1", - "type": "migrate1", - "ricardian_contract": "" - }, - { - "name": "migrate2", - "type": "migrate2", - "ricardian_contract": "" - }, - { - "name": "migraterank", - "type": "migraterank", - "ricardian_contract": "" - }, - { - "name": "newperiod", - "type": "newperiod", - "ricardian_contract": "" - }, - { - "name": "nominate", - "type": "nominate", - "ricardian_contract": "" - }, - { - "name": "nominatecane", - "type": "nominatecane", - "ricardian_contract": "" - }, - { - "name": "paycpu", - "type": "paycpu", - "ricardian_contract": "" - }, - { - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "" - }, - { - "name": "rejectcuspay", - "type": "rejectcuspay", - "ricardian_contract": "" - }, - { - "name": "removecand", - "type": "removecand", - "ricardian_contract": "" - }, - { - "name": "removecstvte", - "type": "removecstvte", - "ricardian_contract": "" - }, - { - "name": "removecuspay", - "type": "removecuspay", - "ricardian_contract": "" - }, - { - "name": "resigncust", - "type": "resigncust", - "ricardian_contract": "" - }, - { - "name": "runnewperiod", - "type": "runnewperiod", - "ricardian_contract": "" - }, - { - "name": "setbudget", - "type": "setbudget", - "ricardian_contract": "" - }, - { - "name": "setperm", - "type": "setperm", - "ricardian_contract": "" - }, - { - "name": "stakeobsv", - "type": "stakeobsv", - "ricardian_contract": "" - }, - { - "name": "stprofile", - "type": "stprofile", - "ricardian_contract": "" - }, - { - "name": "tstaddcust", - "type": "tstaddcust", - "ricardian_contract": "" - }, - { - "name": "unregproxy", - "type": "unregproxy", - "ricardian_contract": "" - }, - { - "name": "unsetbudget", - "type": "unsetbudget", - "ricardian_contract": "" - }, - { - "name": "updatebio", - "type": "updatebio", - "ricardian_contract": "" - }, - { - "name": "updateconfige", - "type": "updateconfige", - "ricardian_contract": "" - }, - { - "name": "updatereqpay", - "type": "updatereqpay", - "ricardian_contract": "" - }, - { - "name": "votecust", - "type": "votecust", - "ricardian_contract": "" - }, - { - "name": "voteproxy", - "type": "voteproxy", - "ricardian_contract": "" - }, - { - "name": "weightobsv", - "type": "weightobsv", - "ricardian_contract": "" - }, - { - "name": "withdrawcane", - "type": "withdrawcane", - "ricardian_contract": "" - } - ], - "tables": [ - { - "name": "candidates", - "type": "candidate", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "candperms", - "type": "candperm", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "config2", - "type": "contr_config", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "custodians", - "type": "custodian", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "custodians2", - "type": "custodian2", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "dacglobals", - "type": "dacglobals", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "pendingpay", - "type": "pay", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "proxies", - "type": "proxy", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "state2", - "type": "contr_state2", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "votes", - "type": "vote", - "index_type": "i64", - "key_names": [], - "key_types": [] - } - ], - "kv_tables": {}, - "ricardian_clauses": [], - "variants": [ - { - "name": "variant_int8_uint8_int32_uint32_int64_uint64_int128_uint128_bool_int64[]_name_string_time_point_sec_asset_extended_asset", - "types": ["int8","uint8","int32","uint32","int64","uint64","int128","uint128","bool","int64[]","name","string","time_point_sec","asset","extended_asset"] - }, - { - "name": "variant_uint32_uint64_int64_bool_int64[]_name_string_time_point_sec", - "types": ["uint32","uint64","int64","bool","int64[]","name","string","time_point_sec"] - } - ], - "action_results": [] -} \ No newline at end of file diff --git a/daccustodian.old/daccustodian.wasm b/daccustodian.old/daccustodian.wasm deleted file mode 100755 index 500f6556..00000000 Binary files a/daccustodian.old/daccustodian.wasm and /dev/null differ