Skip to content

Commit

Permalink
Merge pull request #297 from fioprotocol/feature/FIP-40-fiocontracts-…
Browse files Browse the repository at this point in the history
…dev-03172023

FIP-40  establish permissions, integrate register_address_on_domain.
  • Loading branch information
edrotthoff authored May 4, 2023
2 parents e43667a + 4d5fa02 commit 5ecc1f3
Show file tree
Hide file tree
Showing 18 changed files with 986 additions and 27 deletions.
1 change: 1 addition & 0 deletions contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ add_subdirectory(fio.request.obt)
add_subdirectory(fio.tpid)
add_subdirectory(fio.treasury)
add_subdirectory(fio.escrow)
add_subdirectory(fio.perms)
add_subdirectory(fio.staking)
2 changes: 2 additions & 0 deletions contracts/eosio.msig/src/eosio.msig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ namespace eosio {
_proposer == fioio::TREASURYACCOUNT ||
_proposer == fioio::FIOSYSTEMACCOUNT ||
_proposer == fioio::FIOACCOUNT ||
//FIP-40
_proposer == fioio::PERMSACCOUNT ||
isTopProd)
) {
//collect fees.
Expand Down
96 changes: 88 additions & 8 deletions contracts/fio.address/fio.address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @license FIO Foundation ( https://github.com/fioprotocol/fio/blob/master/LICENSE ) Dapix
*/


#include "fio.address.hpp"
#include <fio.fee/fio.fee.hpp>
#include <fio.common/fio.common.hpp>
Expand All @@ -13,6 +14,7 @@
#include <eosiolib/asset.hpp>
#include <fio.request.obt/fio.request.obt.hpp> //TEMP FOR XFERADDRESS
#include <fio.escrow/fio.escrow.hpp>
#include <fio.perms/fio.perms.hpp>

namespace fioio {

Expand All @@ -33,6 +35,8 @@ namespace fioio {
eosiosystem::producers_table producers;
eosiosystem::locked_tokens_table lockedTokensTable;
nfts_table nftstable;
permissions_table permissions_table;
access_table accesses_table;
config appConfig;

//FIP-39 begin
Expand All @@ -56,8 +60,9 @@ namespace fioio {
voters(SYSTEMACCOUNT, SYSTEMACCOUNT.value),
topprods(SYSTEMACCOUNT, SYSTEMACCOUNT.value),
producers(SYSTEMACCOUNT, SYSTEMACCOUNT.value),
lockedTokensTable(SYSTEMACCOUNT,
SYSTEMACCOUNT.value),
lockedTokensTable(SYSTEMACCOUNT,SYSTEMACCOUNT.value),
permissions_table(PERMSACCOUNT,PERMSACCOUNT.value),
accesses_table(PERMSACCOUNT,PERMSACCOUNT.value),
//FIP-39 begin
fionameinfo(_self, _self.value){
//FIP-39 end
Expand Down Expand Up @@ -282,7 +287,40 @@ namespace fioio {
const bool isPublic = domains_iter->is_public;
uint64_t domain_owner = domains_iter->account;

if (!isPublic) {
bool hasDomainAccess = false;

//if actor is NOT owner, check for permissions
if(actor.value != domain_owner) {

name grantor_account = name(domain_owner);
name grantee_account = actor;
string permctrl =
grantor_account.to_string() + REGISTER_ADDRESS_ON_DOMAIN_OBJECT_TYPE + fa.fiodomain + REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME;
uint128_t permctrlhash = string_to_uint128_hash(permctrl.c_str());
auto permissionbyctrl = permissions_table.get_index<"bypermctrl"_n>();
auto permsbypermctrl_iter = permissionbyctrl.find(permctrlhash);

if (permsbypermctrl_iter == permissionbyctrl.end()) {
permissionbyctrl = permissions_table.get_index<"bypermctrl"_n>();
permctrl =
grantor_account.to_string() + REGISTER_ADDRESS_ON_DOMAIN_OBJECT_TYPE + "*" + REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME;
permctrlhash = string_to_uint128_hash(permctrl.c_str());
permsbypermctrl_iter = permissionbyctrl.find(permctrlhash);

}

if(permsbypermctrl_iter != permissionbyctrl.end()){
string accessctrl = actor.to_string() + to_string(permsbypermctrl_iter->id);
uint128_t accessctrlhash = string_to_uint128_hash(accessctrl.c_str());
auto accessesbyctrl = accesses_table.get_index<"byaccess"_n>();
auto accessesbyctrl_iter = accessesbyctrl.find(accessctrlhash);
if (accessesbyctrl_iter != accessesbyctrl.end()) {
hasDomainAccess = true;
}
}
}

if (!(isPublic || hasDomainAccess)) {
fio_400_assert(domain_owner == actor.value, "fio_address", fa.fioaddress,
"FIO Domain is not public. Only owner can create FIO Addresses.",
ErrorInvalidFioNameFormat);
Expand Down Expand Up @@ -1354,10 +1392,30 @@ namespace fioio {
while (domainiter != domains.end()) {
const uint64_t expire = domainiter->expiration;
if ((expire + DOMAINWAITFORBURNDAYS) < nowtime) {
name grantor_account = name(domainiter->account);
string permcontrol = grantor_account.to_string() + REGISTER_ADDRESS_ON_DOMAIN_OBJECT_TYPE + domainiter->name + REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME;
const uint128_t permcontrolHash = string_to_uint128_hash(permcontrol.c_str());
auto permissionsbycontrolhash = permissions_table.get_index<"bypermctrl"_n>();
auto permctrl_iter = permissionsbycontrolhash.find(permcontrolHash);
if (permctrl_iter != permissionsbycontrolhash.end() ) {
// clear all the permissions for this domain.
//FIP-40
action(
permission_level{get_self(), "active"_n},
"fio.perms"_n,
"clearperm"_n,
std::make_tuple(grantor_account, REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME, domainiter->name)
).send();

// increment the number record processed by one
//this increment helps manage the time used by the burn
recordProcessed++;
if (recordProcessed == numbertoburn) { break; }
}

const auto domainhash = domainiter->domainhash;
auto nameexpidx = fionames.get_index<"bydomain"_n>();
auto nameiter = nameexpidx.find(domainhash);

while (nameiter != nameexpidx.end()) {
auto nextname = nameiter;
nextname++;
Expand Down Expand Up @@ -2021,7 +2079,7 @@ namespace fioio {
uint16_t counter = 0;
auto nft_iter = contractsbyname.begin();
while (nftburnq_iter != burnqbyname.end()) {
nft_iter = contractsbyname.find(nftburnq_iter->fio_address_hash);
nft_iter = contractsbyname.find(nftburnq_iter->fio_address_hash);
counter++;
if (nft_iter != contractsbyname.end()) { // if row, delete an nft
nft_iter = contractsbyname.erase(nft_iter);
Expand Down Expand Up @@ -2407,6 +2465,27 @@ namespace fioio {
a.account = nm.value;
});

//clear all the permissions for this domain as part of the transfer
//note we limit grantees to 100 in the protocol to permit this kind of operation.
//see fio.perms.hpp MAX_GRANTEES documentation for further details.
//FIP-40

string permcontrol = actor.to_string() + REGISTER_ADDRESS_ON_DOMAIN_OBJECT_TYPE + fio_domain + REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME;
const uint128_t permcontrolHash = string_to_uint128_hash(permcontrol.c_str());
auto permissionsbycontrolhash = permissions_table.get_index<"bypermctrl"_n>();
auto permctrl_iter = permissionsbycontrolhash.find(permcontrolHash);
if (permctrl_iter != permissionsbycontrolhash.end() ) {
// clear all the permissions for this domain.
//FIP-40
action(
permission_level{get_self(), "active"_n},
"fio.perms"_n,
"clearperm"_n,
std::make_tuple(actor, REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME, fio_domain)
).send();
}


//fees
const uint64_t fee_amount = fee_iter->suf_amount;
const uint64_t fee_type = fee_iter->type;
Expand Down Expand Up @@ -2516,9 +2595,10 @@ namespace fioio {
void decrcounter(const string &fio_address, const int32_t &step) {

check(step > 0, "step must be greater than 0");
//FIP-40
check((has_auth(AddressContract) || has_auth(TokenContract) || has_auth(TREASURYACCOUNT) || has_auth(STAKINGACCOUNT) ||
has_auth(REQOBTACCOUNT) || has_auth(SYSTEMACCOUNT) || has_auth(FeeContract)),
"missing required authority of fio.address, fio.token, fio.fee, fio.treasury, fio.reqobt, fio.system, fio.staking ");
has_auth(REQOBTACCOUNT) || has_auth(SYSTEMACCOUNT) || has_auth(FeeContract) || has_auth(PERMSACCOUNT)),
"missing required authority of fio.address, fio.token, fio.fee, fio.treasury, fio.reqobt, fio.system, fio.staking fio.perms");

auto namesbyname = fionames.get_index<"byname"_n>();
auto fioname_iter = namesbyname.find(string_to_uint128_hash(fio_address.c_str()));
Expand Down Expand Up @@ -2580,7 +2660,7 @@ namespace fioio {

};

EOSIO_DISPATCH(FioNameLookup, (regaddress)(addaddress)(remaddress)(remalladdr)(regdomain)(renewdomain)(renewaddress)
EOSIO_DISPATCH(FioNameLookup,(regaddress)(addaddress)(remaddress)(remalladdr)(regdomain)(renewdomain)(renewaddress)
(setdomainpub)(burnexpired)(decrcounter)(bind2eosio)(burnaddress)(xferdomain)(xferaddress)(addbundles)(xferescrow)
(addnft)(remnft)(remallnfts)(burnnfts)(regdomadd)(updcryptkey))
}
2 changes: 2 additions & 0 deletions contracts/fio.common/fio.accounts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace fioio {
static const name EscrowContract = name("fio.escrow");
static const name FIOACCOUNT = name("fio");
static const name FIOORACLEContract = name("fio.oracle");
//FIP-40
static const name PERMSACCOUNT = name("fio.perms");

static constexpr name FIOISSUER = name("eosio"_n);
static constexpr eosio::symbol FIOSYMBOL = eosio::symbol("FIO", 9);
Expand Down
11 changes: 10 additions & 1 deletion contracts/fio.common/fio.common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
#define ADD_NFT_ENDPOINT "add_nft"
#define REM_NFT_ENDPOINT "remove_nft"
#define REM_ALL_NFTS_ENDPOINT "remove_all_nfts"
//FIP-40
#define ADD_PERMISSION_ENDPOINT "add_fio_permission"
#define REMOVE_PERMISSION_ENDPOINT "remove_fio_permission"
#define PERMISSION_OBJECT_TYPE_DOMAIN "domain"
//FIP-38 begin
#define NEW_FIO_CHAIN_ACCOUNT_ENDPOINT "new_fio_chain_account"
//FIP-38 end
Expand Down Expand Up @@ -145,7 +149,9 @@ namespace fioio {
actor == fioio::FIOSYSTEMACCOUNT ||
actor == fioio::FIOACCOUNT ||
actor == fioio::EscrowContract ||
actor == FIOORACLEContract);
actor == FIOORACLEContract ||
//FIP-40
actor == PERMSACCOUNT);
}

static constexpr uint64_t string_to_uint64_hash(const char *str) {
Expand Down Expand Up @@ -514,6 +520,9 @@ namespace fioio {
static const uint64_t BUNDLEVOTERAM = 0; //integrated.
static const uint64_t ADDNFTRAMBASE = 512;
static const uint64_t ADDNFTRAM = 2048;
//FIP-40
static const uint64_t ADDPERMISSIONRAMBASE = 2560;
static const uint64_t ADDPERMISSIONRAM = 2048;
static const uint64_t LISTDOMAINRAM = 1536; // FIOESCROW - List Domain 1140 bytes round to 512 x 3
//FIP-38 begin
static const uint64_t NEWFIOCHAINACCOUNTRAM = 0;
Expand Down
18 changes: 17 additions & 1 deletion contracts/fio.common/fio_common_validator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ namespace fioio {
return true;
}

inline bool validateFioNameFormatTPID(const FioAddress &fa) {
if (fa.domainOnly) {
return false;
} else {
if (fa.fioaddress.size() < 3 || fa.fioaddress.size() > maxFioLen) {
return false;
}
if (!validateCharName(fa.fioname) || !validateCharName(fa.fiodomain)) {
return false;
};
}

return true;
}


inline bool validateFioNameFormat(const FioAddress &fa) {
if (fa.domainOnly) {
if (fa.fiodomain.size() < 1 || fa.fiodomain.size() > maxFioDomainLen) {
Expand Down Expand Up @@ -107,7 +123,7 @@ namespace fioio {
if (tpid.size() > 0) {
FioAddress fa;
getFioAddressStruct(tpid, fa);
return validateFioNameFormat(fa);
return validateFioNameFormatTPID(fa);
}
return true;
}
Expand Down
6 changes: 6 additions & 0 deletions contracts/fio.common/fioerror.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ namespace fioio {
constexpr auto ErrorRetireQuantity = ident | httpDataError | 159;
constexpr auto ErrorInvalidMemo = ident | httpDataError | 160;
constexpr auto ErrorDomainSaleNotFound = ident | httpInvalidError | 161; // domain not found in domainsales table
//FIP-40
constexpr auto ErrorInvalidPermissionName = ident | httpDataError | 162;
constexpr auto ErrorInvalidPermissionInfo = ident | httpDataError | 163;
constexpr auto ErrorInvalidObjectName = ident | httpDataError | 164;
constexpr auto ErrorInvalidGranteeAccount = ident | httpDataError | 165;
constexpr auto ErrorPermissionExists = ident | httpDataError | 166;

/**
* Helper funtions for detecting rich error messages and extracting bitfielded values
Expand Down
14 changes: 14 additions & 0 deletions contracts/fio.perms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_contract(fio.perms fio.perms ${CMAKE_CURRENT_SOURCE_DIR}/fio.perms.cpp)

target_include_directories(fio.perms
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../fio.perms/include
${CMAKE_CURRENT_SOURCE_DIR}/../fio.address/include
${CMAKE_CURRENT_SOURCE_DIR}/../
)


set_target_properties(fio.perms
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
Loading

0 comments on commit 5ecc1f3

Please sign in to comment.