Skip to content

Commit

Permalink
Merge pull request #236 from fioprotocol/feature/FIP-41-develop-03012022
Browse files Browse the repository at this point in the history
FIP-41 development iteration
  • Loading branch information
ericbutz committed Mar 22, 2022
2 parents 608e58a + 5447056 commit 5a55ecb
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 27 deletions.
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

0 comments on commit 5a55ecb

Please sign in to comment.