Skip to content

Commit

Permalink
feat(adapter): support only one token per adapter contract
Browse files Browse the repository at this point in the history
  • Loading branch information
envin3 committed Nov 7, 2024
1 parent 14741f9 commit 9bb3704
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 78 deletions.
87 changes: 40 additions & 47 deletions cpp/contracts/adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,23 @@ namespace eosio {

asset adapter::calculate_fees(const asset& quantity) {
registry_adapter _registry(get_self(), get_self().value);
auto idx = _registry.get_index<adapter_registry_idx_xtoken>();
auto search_token = _registry.find(quantity.symbol.code().raw());
auto search_xerc20 = idx.find(quantity.symbol.code().raw());

asset min_fee;
if (search_token != _registry.end()) {
min_fee = search_token->min_fee;
} else if (search_xerc20 != idx.end()) {
min_fee = search_xerc20->min_fee;
} else {
check(false, "invalid quantity given for calculating the fees");
}
check(_registry.exists(), "contract not inizialized");
adapter_registry_table registry_data = _registry.get();

check(
quantity.symbol == registry_data.token_symbol ||
quantity.symbol == registry_data.xerc20_symbol,
"invalid quantity given for calculating the fees"
);

// Fees are expressed in the wrapped token (xerc20), hence why
// the min_fee.symbol
auto ref_symbol = min_fee.symbol;
auto ref_symbol = registry_data.min_fee.symbol;

uint128_t fee_amount = (FEE_BASIS_POINTS * quantity.amount) / FEE_BASIS_POINTS_DIVISOR;
asset fee = asset(fee_amount, ref_symbol);

return fee < min_fee ? min_fee : fee;
return fee < registry_data.min_fee ? registry_data.min_fee : fee;
}

void adapter::check_symbol_is_valid(const name& account, const symbol& sym) {
Expand All @@ -42,34 +38,32 @@ void adapter::create(
const asset& min_fee
) {
require_auth(get_self());
registry_adapter _registry(get_self(), get_self().value);
check(!_registry.exists(), "adapter already registered");

auto _token_bytes = token_bytes.extract_as_byte_array();
check(is_account(xerc20), "xERC20 account does not exist");
check(min_fee.symbol == xerc20_symbol, "invalid minimum fee symbol");

registry_adapter _registry(get_self(), get_self().value);
auto itr = _registry.find(token_symbol.code().raw());
check(itr == _registry.end(), "token already registered");
check_symbol_is_valid(xerc20, xerc20_symbol);

if (token != name(0)) {
// Check token symbol if toekn is local to a EOS like chain
// checks done only for local token
check_symbol_is_valid(token, token_symbol);
// Difference in precision allowed if token is not local
check(token_symbol.precision() == xerc20_symbol.precision(), "invalid xerc20 precision");
// Do not check token validity if token is not local
check(is_account(token), "token account does not exist");
}

checksum256 c;
_registry.emplace( get_self(), [&]( auto& r ) {
r.xerc20 = xerc20;
r.xerc20_symbol = xerc20_symbol;
r.token = token;
r.token_symbol = token_symbol;
r.token_bytes = token_bytes;
r.min_fee = min_fee;
});
symbol non_local_token_symbol = symbol(symbol_code("XXX"), 0);

adapter_registry_table registry_data {
.token = token,
.token_symbol = token == name(0) ? non_local_token_symbol : token_symbol,
.token_bytes = token_bytes,
.xerc20 = xerc20,
.xerc20_symbol = xerc20_symbol,
.min_fee = min_fee
};
_registry.set(registry_data, get_self());

storage _storage(get_self(), get_self().value);
_storage.get_or_create(get_self(), adapter::empty_storage);
Expand Down Expand Up @@ -191,10 +185,10 @@ void adapter::settle(const name& caller, const operation& operation, const metad
require_auth(caller);

registry_adapter _registry(get_self(), get_self().value);
auto idx_registry = _registry.get_index<adapter_registry_idx_token_bytes>();
auto search_token_bytes = idx_registry.find(operation.token);
check(search_token_bytes != idx_registry.end(), "underlying token does not match with adapter registry");
check(search_token_bytes->xerc20_symbol == operation.amount.symbol, "registered xerc20 symbols differs from the operation one"); // TODO: test me
check(_registry.exists(), "contract not inizialized");
adapter_registry_table registry_data = _registry.get();
check (registry_data.token_bytes == operation.token, "underlying token does not match with adapter registry");
check(registry_data.xerc20_symbol == operation.amount.symbol, "registered xerc20 symbols differs from the operation one"); // TODO: test me

checksum256 event_id; // output
pam::check_authorization(get_self(), operation, metadata, event_id);
Expand All @@ -216,13 +210,13 @@ void adapter::settle(const name& caller, const operation& operation, const metad
storage.nonce++;
_storage.set(storage, get_self());

name xerc20 = search_token_bytes->xerc20;
name xerc20 = registry_data.xerc20;
check(is_account(xerc20), "Not valid xerc20 name");
if (operation.amount.amount > 0) {
asset quantity(operation.amount.amount, search_token_bytes->xerc20_symbol);
asset quantity(operation.amount.amount, registry_data.xerc20_symbol);

lockbox_singleton _lockbox(xerc20, xerc20.value);
action_mint _mint(search_token_bytes->xerc20, {get_self(), "active"_n});
action_mint _mint(registry_data.xerc20, {get_self(), "active"_n});
if (_lockbox.exists()) {
// If the lockbox exists, we release the collateral
auto lockbox = _lockbox.get();
Expand Down Expand Up @@ -342,19 +336,18 @@ void adapter::ontransfer(const name& from, const name& to, const asset& quantity
check(quantity.amount > 0, "invalid amount");

registry_adapter _registry(get_self(), get_self().value);
auto search_token = _registry.find(quantity.symbol.code().raw());
auto idx = _registry.get_index<adapter_registry_idx_xtoken>();
auto search_xerc20 = idx.find(quantity.symbol.code().raw());
check(_registry.exists(), "contract not inizialized");
adapter_registry_table registry_data = _registry.get();

bool is_token_transfer = search_token != _registry.end();
bool is_xerc20_transfer = search_xerc20 != idx.end();
bool is_token_transfer = registry_data.token_symbol == quantity.symbol;
bool is_xerc20_transfer = registry_data.xerc20_symbol == quantity.symbol;

check(is_token_transfer || is_xerc20_transfer, "token not registered");
check(is_token_transfer || is_xerc20_transfer, "token not supported by this adapter");

auto xerc20 = is_token_transfer ? search_token->xerc20 : search_xerc20->xerc20;
auto xerc20_symbol = is_token_transfer ? search_token->xerc20_symbol : search_xerc20->xerc20_symbol;
auto token = is_token_transfer ? search_token->token : search_xerc20->token;
auto token_symbol = is_token_transfer ? search_token->token_symbol : search_xerc20->token_symbol;
auto xerc20 = is_token_transfer ? registry_data.xerc20 : registry_data.xerc20;
auto xerc20_symbol = is_token_transfer ? registry_data.xerc20_symbol : registry_data.xerc20_symbol;
auto token = is_token_transfer ? registry_data.token : registry_data.token;
auto token_symbol = is_token_transfer ? registry_data.token_symbol : registry_data.token_symbol;

if (is_token_transfer) check(quantity.symbol == token_symbol, "invalid token quantity symbol");
if (is_xerc20_transfer) check(quantity.symbol == xerc20_symbol, "invalid xerc20 quantity symbol");
Expand Down
7 changes: 1 addition & 6 deletions cpp/contracts/adapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,8 @@ namespace eosio {
typedef eosio::multi_index<"userdata"_n, user_data_table> user_data;
typedef eosio::multi_index<"pastevents"_n, adapter_past_events_table, adapter_past_events_byeventid> past_events;
typedef eosio::multi_index<"reglockbox"_n, lockbox_registry_table, lockbox_registry_byxtoken> registry_lockbox;
typedef eosio::multi_index<
"regadapter"_n,
adapter_registry_table,
adapter_registry_byxtoken,
adapter_registry_bytokenbytes
> registry_adapter;

using registry_adapter = singleton<"regadapter"_n, adapter_registry_table>;
using lockbox_singleton = singleton<"lockbox"_n, name>;
using storage = singleton<"storage"_n, global_storage_table>;

Expand Down
26 changes: 1 addition & 25 deletions cpp/contracts/tables/adapter_registry.table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,13 @@ namespace eosio {
// |_____token____|___token_symbol___|______token_bytes_______|_____xerc20_____|
// | '' | '0,XXX' | bytes32(address(WETH)) | 'xweth.token' |
// NOTE: for not local token_symbol = '0,XXX'

TABLE adapter_registry_table {
name token;
symbol token_symbol;
checksum256 token_bytes;
name xerc20;
symbol xerc20_symbol;
asset min_fee;

uint64_t primary_key() const { return token_symbol.code().raw(); }
uint64_t secondary_key() const { return xerc20_symbol.code().raw(); }
const checksum256& ternary_key() const { return token_bytes; }
};

constexpr name adapter_registry_idx_xtoken = "byxtoken1"_n;
constexpr name adapter_registry_idx_token_bytes = "bytokenbytes"_n;

typedef indexed_by<
adapter_registry_idx_xtoken,
const_mem_fun<
adapter_registry_table,
uint64_t,
&adapter_registry_table::secondary_key
>
> adapter_registry_byxtoken;

typedef indexed_by<
adapter_registry_idx_token_bytes,
const_mem_fun<
adapter_registry_table,
const checksum256&,
&adapter_registry_table::ternary_key
>
> adapter_registry_bytokenbytes;
}

0 comments on commit 9bb3704

Please sign in to comment.