Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIP-41 development iteration #236

Merged
merged 1 commit into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions contracts/fio.common/fio.common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,15 @@ namespace fioio {
"fdtnrwdupdat"_n,
std::make_tuple((uint64_t)(static_cast<double>(amount) * .05))
).send();

//call action to check general locks for clearing.
action(
permission_level{auth, "active"_n},
SYSTEMACCOUNT, "clrgenlocked"_n,
make_tuple(actor)
).send();


fionames_table fionames(AddressContract, AddressContract.value);
uint128_t fioaddhash = string_to_uint128_hash(tpid.c_str());

Expand Down
3 changes: 3 additions & 0 deletions contracts/fio.system/include/fio.system/fio.system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ class [[eosio::contract("fio.system")]] system_contract : public native {
void modgenlocked(const name &owner, const vector<lockperiodv2> &periods, const int64_t &amount,const int64_t &rem_lock_amount,
const uint32_t &payouts);

[[eosio::action]]
void clrgenlocked(const name &owner);

[[eosio::action]]
void setnolimits(const name &account);

Expand Down
26 changes: 23 additions & 3 deletions contracts/fio.system/src/fio.system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ namespace eosiosystem {
const int64_t &amount, const int64_t &rem_lock_amount,
const uint32_t &payouts) {

eosio_assert( has_auth(StakingContract),
"missing required authority of fio.staking");
eosio_assert( has_auth(StakingContract) || has_auth(TokenContract),
"missing required authority of fio.staking or fio.token");

check(is_account(owner),"account must pre exist");
check(amount > 0,"cannot add locked token amount less or equal 0.");
Expand Down Expand Up @@ -293,14 +293,34 @@ namespace eosiosystem {
});
}


//this action will check if all periods are in the past and clear the general locks if all of them are in the past.
void eosiosystem::system_contract::clrgenlocked(const name &owner) {

eosio_assert((has_auth(AddressContract) || has_auth(TokenContract) || has_auth(TREASURYACCOUNT) ||
has_auth(STAKINGACCOUNT) ||has_auth(REQOBTACCOUNT) || has_auth(SYSTEMACCOUNT) || has_auth(FeeContract) || has_auth(EscrowContract)),
"missing required authority of fio.address, fio.token, fio.fee, fio.treasury, fio.escrow, fio.staking, or fio.reqobt");
check(is_account(owner),"account must pre exist");
auto locks_by_owner = _generallockedtokens.get_index<"byowner"_n>();
auto lockiter = locks_by_owner.find(owner.value);
if (lockiter != locks_by_owner.end()) {
uint32_t present_time = now();
//never clear another accounts stuff.
if ((lockiter->owner_account == owner) &&
( ((lockiter->periods[lockiter->periods.size()-1].duration + lockiter->timestamp) < present_time) ||
lockiter->periods.size() == 0)) {
locks_by_owner.erase(lockiter);
}
}
}
} /// fio.system


EOSIO_DISPATCH( eosiosystem::system_contract,
// native.hpp (newaccount definition is actually in fio.system.cpp)
(newaccount)(addaction)(remaction)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi)
// fio.system.cpp
(init)(setnolimits)(addlocked)(addgenlocked)(modgenlocked)(setparams)(setpriv)
(init)(setnolimits)(addlocked)(addgenlocked)(modgenlocked)(clrgenlocked)(setparams)(setpriv)
(rmvproducer)(updtrevision)
// delegate_bandwidth.cpp
(updatepower)
Expand Down
67 changes: 67 additions & 0 deletions contracts/fio.token/include/fio.token/fio.token.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,73 @@ namespace eosio {
}


//this action will recalculate durations from the specific timestampforperiods to the specified targettimestamp
static vector<eosiosystem::lockperiodv2> recalcdurations( const vector<eosiosystem::lockperiodv2> &periods,
const uint32_t targettimestamp,
const uint32_t timestampofperiods,
const uint64_t amount) {
check(targettimestamp < timestampofperiods,"illegal timestamp for reset of locking periods");
vector <eosiosystem::lockperiodv2> newperiods;
uint32_t duration_delta = timestampofperiods - targettimestamp;
uint64_t tota = 0;
for(int i=0;i<periods.size();i++){
fio_400_assert(periods[i].amount > 0, "unlock_periods", "Invalid unlock periods",
"Invalid amount value in unlock periods", ErrorInvalidUnlockPeriods);
fio_400_assert(periods[i].duration > 0, "unlock_periods", "Invalid unlock periods",
"Invalid duration value in unlock periods", ErrorInvalidUnlockPeriods);
tota += periods[i].amount;
if (i>0){
fio_400_assert(periods[i].duration > periods[i-1].duration, "unlock_periods", "Invalid unlock periods",
"Invalid duration value in unlock periods, must be sorted", ErrorInvalidUnlockPeriods);
}
eosiosystem::lockperiodv2 iperiod;
iperiod.duration = periods[i].duration + duration_delta;
iperiod.amount = periods[i].amount;
newperiods.push_back(iperiod);
}
fio_400_assert(tota == amount, "unlock_periods", "Invalid unlock periods",
"Invalid total amount for unlock periods", ErrorInvalidUnlockPeriods);
return newperiods;
}

static vector<eosiosystem::lockperiodv2> mergeperiods( const vector<eosiosystem::lockperiodv2> &op1,
const vector<eosiosystem::lockperiodv2> &op2
) {
vector <eosiosystem::lockperiodv2> newperiods;
check(op1.size() > 0,"illegal size op1 periods");
check(op2.size() > 0,"illegal size op1 periods");
check(op1.size() + op2.size() <= 50,
"illegal number of periods results from merge, cannot merge two lists that have more than 50 periods total");
int op1idx = 0;
int op2idx = 0;
while ((op1idx < op1.size() ) || (op2idx < op2.size())) {
while (op2idx < op2.size() &&
(op1idx >= op1.size() || (op2[op2idx].duration < op1[op1idx].duration))) {
eosiosystem::lockperiodv2 iperiod;
iperiod.duration = op2[op2idx].duration;
iperiod.amount = op2[op2idx].amount;
newperiods.push_back(iperiod);
op2idx++;
}
while (op1idx < op1.size() &&
(op2idx >= op2.size() || (op1[op1idx].duration < op2[op2idx].duration))){
eosiosystem::lockperiodv2 iperiod;
iperiod.duration = op1[op1idx].duration;
iperiod.amount = op1[op1idx].amount;
newperiods.push_back(iperiod);
op1idx++;
}
if ((op2idx < op2.size() && (op1idx < op1.size())) &&
(op2[op2idx].duration == op1[op1idx].duration)){
eosiosystem::lockperiodv2 iperiod;
iperiod.duration = op2[op2idx].duration;
iperiod.amount = op2[op2idx].amount + op1[op1idx].amount;
newperiods.push_back(iperiod);
op2idx++;
op1idx++;
}
}
return newperiods;
}
};
} /// namespace eosio
74 changes: 50 additions & 24 deletions contracts/fio.token/src/fio.token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,23 +502,8 @@ namespace eosio {

fio_400_assert(((periods.size()) >= 1 && (periods.size() <= 50)), "unlock_periods", "Invalid unlock periods",
"Invalid number of unlock periods", ErrorTransactionTooLarge);
uint64_t tota = 0;
double tv = 0.0;

for(int i=0;i<periods.size();i++){
fio_400_assert(periods[i].amount > 0, "unlock_periods", "Invalid unlock periods",
"Invalid amount value in unlock periods", ErrorInvalidUnlockPeriods);
fio_400_assert(periods[i].duration > 0, "unlock_periods", "Invalid unlock periods",
"Invalid duration value in unlock periods", ErrorInvalidUnlockPeriods);
tota += periods[i].amount;
if (i>0){
fio_400_assert(periods[i].duration > periods[i-1].duration, "unlock_periods", "Invalid unlock periods",
"Invalid duration value in unlock periods, must be sorted", ErrorInvalidUnlockPeriods);
}
}

fio_400_assert(tota == amount, "unlock_periods", "Invalid unlock periods",
"Invalid total amount for unlock periods", ErrorInvalidUnlockPeriods);
uint32_t present_time = now();

fio_400_assert(((can_vote == 0)||(can_vote == 1)), "can_vote", to_string(can_vote),
"Invalid can_vote value", ErrorInvalidValue);
Expand Down Expand Up @@ -550,14 +535,55 @@ namespace eosio {
reg_amount = ninetydayperiods * reg_amount;

//check for pre existing account is done here.
name owner = transfer_public_key(payee_public_key,amount,max_fee,actor,tpid,reg_amount,true);

//if no locked tokens in the account do this.
bool canvote = (can_vote == 1);
INLINE_ACTION_SENDER(eosiosystem::system_contract, addgenlocked)
("eosio"_n, {{_self, "active"_n}},
{owner,periods,canvote,amount}
);
name owner = transfer_public_key(payee_public_key,amount,max_fee,actor,tpid,reg_amount,false);

//FIP-41 new logic for send lock tokens to existing account
auto locks_by_owner = generalLockTokensTable.get_index<"byowner"_n>();
auto lockiter = locks_by_owner.find(owner.value);
if (lockiter != locks_by_owner.end()) {
int64_t newlockamount = lockiter->lock_amount + amount;
int64_t newremaininglockamount = lockiter->remaining_lock_amount + amount;
uint32_t payouts = lockiter->payouts_performed;
bool err1 = (can_vote == 0) && can_vote == lockiter->can_vote;
bool err2 = (can_vote == 1) && can_vote == lockiter->can_vote;
string errmsg = "Locked tokens with restricted voting can only be transferred to a new account.";
if(err2)
{
errmsg = "This account has voting restriction on locked tokens, sending locked tokens without voting restriction is not allowed.";
}
fio_400_assert(err1 || err2, "can_vote", to_string(can_vote),
errmsg, ErrorInvalidValue);
vector<eosiosystem::lockperiodv2> periods_t1 = recalcdurations(periods,lockiter->timestamp, present_time, amount);
vector <eosiosystem::lockperiodv2> newperiods = mergeperiods(periods_t1,lockiter->periods);
action(
permission_level{get_self(), "active"_n},
SYSTEMACCOUNT,
"modgenlocked"_n,
std::make_tuple(owner, newperiods, newlockamount, newremaininglockamount, payouts)
).send();
}else {
uint64_t tota = 0;
double tv = 0.0;

for(int i=0;i<periods.size();i++){
fio_400_assert(periods[i].amount > 0, "unlock_periods", "Invalid unlock periods",
"Invalid amount value in unlock periods", ErrorInvalidUnlockPeriods);
fio_400_assert(periods[i].duration > 0, "unlock_periods", "Invalid unlock periods",
"Invalid duration value in unlock periods", ErrorInvalidUnlockPeriods);
tota += periods[i].amount;
if (i>0){
fio_400_assert(periods[i].duration > periods[i-1].duration, "unlock_periods", "Invalid unlock periods",
"Invalid duration value in unlock periods, must be sorted", ErrorInvalidUnlockPeriods);
}
}
fio_400_assert(tota == amount, "unlock_periods", "Invalid unlock periods",
"Invalid total amount for unlock periods", ErrorInvalidUnlockPeriods);
INLINE_ACTION_SENDER(eosiosystem::system_contract, addgenlocked)
("eosio"_n, {{_self, "active"_n}},
{owner, periods, can_vote, amount}
);
}
// end FIP-41 logic for send lock tokens to existing account

int64_t raminc = 1024 + (64 * periods.size());

Expand Down